LINUX.ORG.RU

QAtomicInt и оператор = и прочие операторы


0

1

У класса QAtomicInt есть не нужные мне функции, такие как testAndSetOrdered и fetchAndStoreOrdered, зато операторы извлечения значения и оператор= это то что мне нужно.

Вопрос: операторы типа = или даже + и прочие... они точно так же защищают переменную от некорректной модификации из нескольких потоков?

Я так понимаю что если не защищать, то в зависимости от фазы Луны при записи в одну переменную нового значения - чтение может дать и не старое и не новое значение числа, а какое-то совсем иное? так?

Добавил: Нашел что всё же эти операторы не безопасны, а только эти неудобные testAndSetOrdered и прочие - безопасны.

Вопрос: как безопасно записать и просто безопасно прочитать значение из QAtomicInt??? testAndSetOrdered - там есть expected value - я то откуда знаю какое оно? я просто хочу тупо записать и тупо прочитать и чтобы это было потокобезопасно (ибо реализовано на асме особым образом под каждую платформу)...

★★★★★

Последнее исправление: I-Love-Microsoft (всего исправлений: 1)

Ответ на: комментарий от quiet_readonly

но мне не надо записывать, либо читать либо записывать

как же тогда пользоваться этим гениальным API если не надо трогать значение переменной а просто вычитать, или допустим я только записываю - вот как мне прочитать не записав?

I-Love-Microsoft ★★★★★
() автор топика

Что значит безопасно?

namezys ★★★★
()
Ответ на: комментарий от quiet_readonly

вот как сделать чтобы оно не записывало новое??? а просто считать или просто записать? никто меня не понимает, гугл тоже =(

если в одном месте пишут а в другом читают - ну явно же каша считается, не?

или я не понял главного, что операции просто чтения - атомарны? прям на всех платформах без исключения?

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от quiet_readonly

лучше иначе сформулирую вопрос: в каких случаях тогда вообще надо защищать от одновременной модификации? только при чтении? а при записи не надо? при записи в любом случае всегда запишется как надо? тогда как только прочитать значение - fetchandstore явно сделает запись, что мне как раз не надо...

в общем, я использую переменные типа int и bool между потоками - и мне не важно будет ли она модифицирована в момент чтения - вот в таком случае я могу вообще забить на этот QAtomicInt или наборот, применять с большим рвением?

меня интересует во что - допустим я читаю int в одном потоке, а в другом пишу одновременно в эту же переменную либо 0x12345678 либо 0xABCD5577 - я всегда при чтении получу одно из этих двух значений либо данные будут искажены, будут записаны только некоторые быйты, не все и получится какое-то третье и более чисел?

если я всегда буду получать корректно либо 0x12345678 либо 0xABCD5577 на любой аппаратной платформе то меня это устроит

мне важно чтобы не возникали ошибочные числа - типа 0x12345577 - часть старого часть нового - вот тогда кранты

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от quiet_readonly

а оно потом будет записано, только значение прежнее? мне это показалось перректальным но видимо просто прочесть никак... могли бы getValue() какой-нибудь сообразить...

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от namezys

так речь о переменных в озу/кэше, а не о регистрах

сначала ты быстро запишешь в регистр, а потом int пишется в озу... обычно всё выровнено по 32 битам и пишется сразу целиком

но ведь qatomicint все же существует как класс буквально

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

вроде как на аппаратном уровне это проверяется. Если нет - то вообще бы ничего не работало. ЕМНП, то учитывать кэш при многопоточности не надо

namezys ★★★★
()
Ответ на: комментарий от I-Love-Microsoft

просто пиши int, это атомарная операция, QAtimicInt нужна именно для того чтобы одновременно проверять и записывать/читать, иначе после проверки значания, при считывании ты можешь получть совсем не то значение которое проверял, т.к. его измнили в другом потоке.

bjorn
()
Ответ на: комментарий от bjorn

оно будет изменено на новое или на не корректное?

меня одно интересует - одновременное чтение-запись на какой-либо платформе может породить некорректные данные при чтении?

т.к. у меня пишется в одном потоке, а читается в остальных - то получается что мне безопасно даже просто пользоваться обычными int без мьютексов? верно?

зато для остальных, любых данных более 32-бит типа QVariantList - я уже использую mutex-ы

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от quiet_readonly

зацени, я сделал такой класс:

sint::sint()
{
	i.fetchAndStoreOrdered(0);
}

void sint::set(int value)
{
	i.fetchAndStoreOrdered(value);
}

int sint::get()
{
	return i.fetchAndAddOrdered(0);
}
вот так безопасно будет? в смысле не будет так, что я записал значение, а второй поток не дал его записать новым?

в смысле что fetchAndAddOrdered с нулем запишет старое значение и помешает чтобы fetchAndStoreOrdered записало новое значение? или как раз используя класс QAtomicInt я могу смело и решительно не думать о таких проблемах?

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от quiet_readonly

привет! сори что пишу, просто есть вопросы ещё

fetchAndStoreOrdered из разных потоков ведь может привести что в одном потоке я записываю 1 (fetchAndStoreOrdered) а второй поток тут же отнимает управление и пишет ноль через fetchAndStoreOrdered, а когда вернусь в первый поток то единица не запишется?

такое ведь не исключается этими атомиками? если в одном месте пишут 0 а в другом 1 (например что повторно возникло событие какое-то и отмечается единицей) - то может ли возникнуть такой момент что я тупо пропускаю событие ибо записался 0?

или такие ситуации надо головой думать, алгоритмически не допускать такого?

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

или такие ситуации надо головой думать, алгоритмически не допускать такого?

В принципе да, ещё там есть операция «проверить значение и если оно равно ожидаемому, то установить новое».

quiet_readonly ★★★★
()
Ответ на: комментарий от quiet_readonly

привет! :) опять я...

для безопасного чтения fetchAndAddOrdered(0) - я погуглил эту строку и понял что результатов крайне мало

что-то здесь не так, не может быть чтобы разработчики Qt не предусмотрели отдельно просто чтение, а оно как я тоже гуглил - неатомарно даже на x86, при незащищенном чтении запросто можно мусор получить

я буду пользоваться fetchAndAddOrdered(0), надеясь что оно то что надо, но всё же

хочу знать всё на 100%, не верить что вроде нормально - а именно быть уверенным, знать :)

я выгуглил что чтение может быть неатомарным на многих процах поэтому защищать точно надо, а вот правильно ли читать с помощью добавления нуля?

представь - мы каждый раз выполняем запись при fetchAndAddOrdered, и вот другой поток записывает 1 вместо нуля, а поток управление возвращается к fetchAndAddOrdered(0) и дописывает ноль в переменную...

или я не понял от чего защищает QAtomicInt - он гарантирует что fetchAndAddOrdered - ну 1000% атомарно и никак иначе??? если так - то вопрос мой был глуп и я его снимаю :)

I-Love-Microsoft ★★★★★
() автор топика
Ответ на: комментарий от I-Love-Microsoft

При возможности и правда лучше использовать STL. Ну а насчёт QAtomicInt, fetchAndAddOrdered прочитает число и тут же прибавит к нему 0. Поскольку при прибавлении нуля число не меняется, то он просто прочитает число.

quiet_readonly ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.