Есть поток, проверяющий несколько раз в секунду некий буловский флаг, и если флаг выставлен, поток завершается.
В то же время некий другой поток естественно однажды этот флаг выставит.
Вопрос: если не делать синхронизацию с помощью критических секций, не случится ли чего плохого, если один поток будет читать флаг в то время как второй будет его выставлять? Вероятность этого конечно весьма и весьма мала (особенно учитывая современные процы), но тем не менее..
Тут же возникает более общий вопрос: а вообще интовый ресурс нужно синхронизировать, если меняет его только один поток, а читают многие?
Здравствуйте, Zline, Вы писали:
Z>Вопрос видимо классический, но тем не менее:
Z>Есть поток, проверяющий несколько раз в секунду некий буловский флаг, и если флаг выставлен, поток завершается. Z>В то же время некий другой поток естественно однажды этот флаг выставит.
Только один вопрос: чем плох мютекс?
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
WARNING: expression "to_be || !to_be" is always true
Здравствуйте, Zline, Вы писали:
Z>Вопрос видимо классический, но тем не менее:
Z>Есть поток, проверяющий несколько раз в секунду некий буловский флаг, и если флаг выставлен, поток завершается. Z>В то же время некий другой поток естественно однажды этот флаг выставит.
Z>Вопрос: если не делать синхронизацию с помощью критических секций, не случится ли чего плохого, если один поток будет читать флаг в то время как второй будет его выставлять? Вероятность этого конечно весьма и весьма мала (особенно учитывая современные процы), но тем не менее..
Z>Тут же возникает более общий вопрос: а вообще интовый ресурс нужно синхронизировать, если меняет его только один поток, а читают многие?
Если не хочется использовать объекты ядра, можно использовать IntelockedIncrement/InterlockedDecrement
оверквотинг был несколько лишний в принципе...
С>Если не хочется использовать объекты ядра, можно использовать IntelockedIncrement/InterlockedDecrement
...но ответ должен быть именно такой. +1!
... << RSDN@Home 1.1.4 beta 7 rev. 447>>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
Z>>Есть поток, проверяющий несколько раз в секунду некий буловский флаг, и если флаг выставлен, поток завершается. Z>>В то же время некий другой поток естественно однажды этот флаг выставит.
A>Только один вопрос: чем плох мютекс?
Как истинный ариец, отвечу вопросом на вопрос — а чем в данном случае он хорош?
Здравствуйте, Zline, Вы писали: Z>Тут же возникает более общий вопрос: а вообще интовый ресурс нужно синхронизировать, если меняет его только один поток, а читают многие?
Если тебе нужен просто вариант "триггера", то можно не синхронизировать.
Даже если обстоятельства позже изменятся и писать в переменную будет не один поток, а несколько, то даже в этом случае вполне можно обойтись без строгой синхронизации.
Поскольку интересен только факт "ноль-не ноль".
Есть только одна потенциальная засада, переменная должна быть объявлена volatile, что от неприятностей с оптимизацией отнюдь не гарантирует.(см. одноимённый многостраницный топик). Я бы всё-таки присоединился к автору, посоветовавшему использовать Interlocked* функции. По той причине, что они содержат примитив, исполняющий роль mfence и может избавить от потенциальных недоразумений с синхронизацией процессорных кэшей.
Пользоваться тяжёлыми методами с привлечением объектов ядра я никакого смысла не вижу.
Здравствуйте, Amidlokos, Вы писали:
Z>>Вопрос видимо классический, но тем не менее: Z>>Есть поток, проверяющий несколько раз в секунду некий буловский флаг, и если флаг выставлен, поток завершается. Z>>В то же время некий другой поток естественно однажды этот флаг выставит. A>Только один вопрос: чем плох мютекс?
Тем, что на его создание и обращение к нему требуется, согласно Рихтеру, на много больше времени, нежели при работе с критическими секциями.
Здравствуйте, Zline, Вы писали:
Z>Вопрос видимо классический, но тем не менее:
И так же классические грабли
Z>Есть поток, проверяющий несколько раз в секунду некий буловский флаг, и если флаг выставлен, поток завершается. Z>В то же время некий другой поток естественно однажды этот флаг выставит.
Кроме того, что он проверяет этот флаг, поток еще что-нибудь делает? В любом случае, я бы воспользовался событиями (CreateEvent / WaitForSingleObject).
Z>Тут же возникает более общий вопрос: а вообще интовый ресурс нужно синхронизировать, если меняет его только один поток, а читают многие?
Спасибо всем за ответы. Вопрос даже не в том мьютекс/критическая секция/события, а в том стоит ли париться с этим (вставляя соотв. код во все обращения) — ресурс то интовый, безхитростный
Наверно остановлюсь на InterLocked-функциях. Спасибо за совет.
Z>Наверно остановлюсь на InterLocked-функциях. Спасибо за совет.
Эм, сори что снова поднимаю тему, но возник еще вопрос: а те потоки, что будут только читать переменную, должны делать какие-либо дополнительные телодвижения? или просто localVar = sharedVar; ?
В поисках ответа я наткнулся на ряд дискуссий по поводу того, нужно ли такую переменную объявить volatile, а также на идею, заключающуюся в том, что все переменные, используемые несколькими потоками должны быть volatile. Так ли это? А если так, то что делать со списковыми структурами, которые юзают много потоков (синхронизация через критические секции конечно есть, а нужен ли тут еще volatile?)
Z>Вопрос: если не делать синхронизацию с помощью критических секций, не случится ли чего плохого, если один поток будет читать флаг в то время как второй будет его выставлять?
Ничего плохого не случится. Критические секции тут АБСОЛЮТНО не нужны.
Z>>Наверно остановлюсь на InterLocked-функциях. Спасибо за совет. Z>Эм, сори что снова поднимаю тему, но возник еще вопрос: а те потоки, что будут только читать переменную, должны делать какие-либо дополнительные телодвижения? или просто localVar = sharedVar; ?
Z>>>Наверно остановлюсь на InterLocked-функциях. Спасибо за совет. Z>>Эм, сори что снова поднимаю тему, но возник еще вопрос: а те потоки, что будут только читать переменную, должны делать какие-либо дополнительные телодвижения? или просто localVar = sharedVar; ?
AB>InterLockedExchange?
Чтобы просто читать, никаких примитивов синхронизации не нужно. Модификатор volatile — нужен.
Z>>Вопрос: если не делать синхронизацию с помощью критических секций, не случится ли чего плохого, если один поток будет читать флаг в то время как второй будет его выставлять?
S> Ничего плохого не случится. Критические секции тут АБСОЛЮТНО не нужны.
AS>>Как истинный ариец, отвечу вопросом на вопрос — а чем в данном случае он хорош?
A>Тем, что таких вопросов не возникнет...
Зато возникнут вопросы у того, кто будет просматривать такой код. Вопросы о квалификации того, кто это писал. Не следует использовать объекты ядра где ни попадя.
Здравствуйте, Andrew S, Вы писали:
AS>Зато возникнут вопросы у того, кто будет просматривать такой код. Вопросы о квалификации того, кто это писал. Не следует использовать объекты ядра где ни попадя.
Межпотоковая синхронизация это как скобки. Лучше поставить лишнюю пару, чем не поставить там где надо.
Здравствуйте, Andrew S, Вы писали:
AB>>InterLockedExchange?
угу, но оно меняет и флаг, а оно мне при чтении не нужно
AS>Чтобы просто читать, никаких примитивов синхронизации не нужно. Модификатор volatile — нужен.
Насчет флага понятно, а теперь volatile =)
Ну допустим флагам я его поставлю. А списковым структурам, которые юзает несколько тредов, как прописывать volatile? всем указателям в структуре и корню структуры?
Здравствуйте, Zline, Вы писали:
Z>Ну допустим флагам я его поставлю. А списковым структурам, которые юзает несколько тредов, как прописывать volatile? всем указателям в структуре и корню структуры?