Это один из тех вопросов, которые, похоже, попадают в категорию «наивно очевидных, но, вероятно, неправильных». Конечно, я изо всех сил пытаюсь найти решение, которое работает во всех угловых случаях. Похоже, это проблема, с которой приходится сталкиваться постоянно.
У меня есть «аппаратный» поток и «обрабатывающий» поток.
Аппаратный поток запускается в закрытой двоичной библиотеке, к которой у меня нет доступа.
Поток обработки регистрирует обратный вызов в аппаратном потоке для уведомления о некоторых (редких) событиях, связанных с изменениями состояния в аппаратном обеспечении.
Я хочу иметь возможность уведомить цикл обработки событий в потоке обработки об изменении состояния. Я хотел бы сделать это, не требуя зависимости от внешней библиотеки или непереносимым способом, и не используя блокировки (поскольку я понятия не имею, когда аппаратный поток может захотеть снова уведомить поток обработки).
Итак, в настоящее время я думаю о том, как решить эту проблему, примерно так:
#include <signal.h>
// sig_atomic_t is used so update is always in a sane state
static volatile sig_atomic_t update = 0;
// called from hardware thread
int callback_function() {
update += 1;
}
// called regularly from processing thread
int processing_function() {
static sig_atomic_t local_update = 0; // The same type as update
if (local_update != update){
update_internal_hardware_state(); // We necessarily call once per callback
local_update += 1;
}
}
Очевидно, что это сломается, если update
обернется и просто достигнет значения local_update
до следующего вызова processing_function
(хотя почти наверняка я могу предположить, что этого никогда не произойдет).
Я пропустил что-то тонкое (или не очень) здесь?
Есть ли лучший способ решить всю эту проблему?
Можно предположить, что обратный вызов всегда вызывается только из одного потока (аппаратного потока).