И чтобы основной код мог надежно прочитать эту переменную, мне нужно использовать мембрану как в обработчике, так и в основном коде.
Нет, просто сделайте это volatile sig_atomic_t
. ISO C гарантирует, что ваш код будет работать без необходимости писать какие-либо явные барьеры в исходном коде. (В основном, как без блокировки _Atomic
с упорядочением mo_relaxed, за исключением упорядоченного по отношению к другим изменчивым доступам.)
И если вам нужен барьер памяти, вам не нужен системный вызов membarrier
, просто asm("" ::: "memory")
, чтобы заставить или хранилище происходить хотя бы раз в al oop.
membarrier()
, может быть полезно, если у вас есть другой поток, выполняющий слабо упорядоченные загрузки из памяти, но который не может быть оптимизирован (поднят из oop). Тогда membarrier()
может превратить эту расслабленную нагрузку на другое ядро в фактически загрузочную загрузку, если вы делаете это между двумя хранилищами в потоке производителя.
Поскольку вы уже используете полный барьер во время компиляции в считыватель (чтобы не допустить подъема энергонезависимой нагрузки из l oop) и проверка флага exit_now или keep_running не имеет порядка упорядочения. другой код, вам это не нужно.
ISO C гарантирует только что-либо за volatile sig_atomic_t
, а не просто sig_atomic_t
(обычно это просто int
). Единственная причина использования sig_atomic_t
состоит в том, что вы используете его с volatile
.
На практике volatile int
будет даже виден другим потокам , а не только между обработчиком сигнала и потоком, который приостановил выполнение обработчика сигнала. (Поскольку настоящие C реализации работают на аппаратном обеспечении, согласованном с кешем, и не определяют аппаратное состязание, и т.д. *. См. Также https://electronics.stackexchange.com/questions/387181/mcu-programming-c-o2-optimization-breaks-while-loop/387478#387478 для атомарности между одним потоком и обработчиком прерывания (или сигнала).
И также смотрите Когда использовать volatile с многопоточностью? - в основном никогда, используйте C11 _Atomic
из stdatomic.h
. Мой ответ объясняет, почему это работает на практике, и что именно происходит.