Во-первых, потоки сложны; -p
Да, несмотря на все слухи об обратном, требуется либо использовать lock
или volatile
(но не оба) при доступе к bool
из нескольких потоков.
Для простых типов и доступа, таких как флаг выхода (bool
), тогда volatile
достаточно - это гарантирует, что потоки не кэшируют значение в своих регистрах (это означает, что один из потоков никогда не видит обновления).
Для больших значений (когда атомарность является проблемой) или где вы хотите синхронизировать последовательности операций (типичным примером является «если не существует и добавить» доступ к словарю), lock
является более универсальным. Это действует как барьер памяти, поэтому дает вам безопасность потока, но предоставляет другие функции, такие как импульс / ожидание. Обратите внимание, что вы не должны использовать lock
для значения типа или string
; ни Type
, ни this
; лучший вариант - иметь свой собственный объект блокировки как поле (readonly object syncLock = new object();
) и заблокировать это.
Пример того, как сильно он ломается (т. е. цикл навсегда), если вы не синхронизируете - см. здесь .
Чтобы охватить несколько программ, может быть полезен примитив ОС, такой как Mutex
или *ResetEvent
, но это избыток для одного exe.