Два потока используют одну переменную
У меня есть два потока: "главный" и "рабочий", и одна глобальная переменная bool isQuitRequested
который будет использоваться main
поток, чтобы сообщить worker
когда пришло время выйти из цикла while (что-то вроде этого: while(isQuitRequested == false) { ... do some stuff ... }
)
Теперь я немного обеспокоен... Нужно ли использовать какую-то мьютексную защиту для isQuitRequested
, учитывая, что только один поток (main
) выполняет isQuitRequested = true
операция, а другая (worker
) просто выполняет проверку и больше ничего?
Я прочитал, что может произойти, если два потока одновременно обращаются к одной и той же переменной bool?, Я что-то похожее, но не та же ситуация...
4 ответа
Вы не указали, какой язык вы используете, и из небольшого фрагмента кода, который вы разместили, это может быть C#, Java или C++. Вот некоторые общие решения для этого "шаблона" для каждого из них:
C#:
volatile bool isQuitRequested;
Джава:
volatile boolean isQuitRequested;
C++: volatile
в C++ это не так полезно. Идти с:
std::atomic<bool> isQuitRequested;
Это должно быть безопасно с volatile
bool, если вы не используете какие-либо данные в потоке потребителя (который проверяет bool), затронутый потоком производителя (который устанавливает bool в значение true), И после того, как ваш поток потребителя обнаружит, что для bool установлено значение true, он не пытается повторно использовать / переустанавливать его как способ связи с потоком производителя (как в примере, на который вы ссылаетесь).
Это потому, что этот случай делает переупорядочение памяти не проблема.
В Java вам нужно только пометить эту переменную как volatile
:
volatile boolean isQuitRequested;
Или использовать AtomicBoolean
, В противном случае изменения, внесенные одним потоком, могут быть не видны другим потокам.
Однако в вашем случае есть встроенный функционал: просто позвоните interrupt()
о потоке и обработайте его, смотрите: Как остановить поток, который работает вечно без какого-либо использования.
Смотрите также:
В соответствии с моим опытом работы с windows глобальной переменной обычно достаточно, если она относится к одному из основных типов char, short, int, long. Если вы хотите сделать это "правильным способом", решение @Tudor выглядит отлично.