Я давно занимаюсь разработкой C ++ для Linux. И когда я разрабатываю некий независимый модуль, обрабатывающий очередь сообщений / задач, я всегда обрабатываю сигнал SIGINT
, чтобы избежать потери сообщения / задачи. Вот пример моего кода:
volatile sig_atomic_t sig = 0;
void sig_handler(int signal)
{
sig = 1;
}
int main()
{
signal(SIGINT,sig_handler);
msg_queue = init_msg_queue();
init_receiving_msg_thread(); // start a thread to receive msgs and push them into msg_queue
while(!sig) {
process_msg(msg_queue.top()); // process the first msg in the queue
msg_queue.pop(); // remove the first msg
}
stop_receiving_msg_thread();
process_all_msgs(msg_queue);
return 0;
}
Что ж, этот фрагмент кода прост: если сигнал SIGINT
захвачен, прекратите прием сообщений, обработайте все сообщения, оставшиеся в очереди, и вернитесь. В противном случае код останется бесконечно долго.
Я думал, что sig_atomic_t
был какой-то черной магией. Поскольку, как я понимаю, функция sig_handler
должна быть реентерабельной функцией, что означает, что она не может содержать никаких статических или глобальных непостоянных данных: Что такое реентерабельная функция?
Поэтому я всегда думал, что sig_atomic_t
- это какая-то хитрость, а не глобальная переменная.
Но сегодня я прочитал эту ссылку: Как на самом деле работает sig_atomic_t?, который сказал мне, что sig_atomic_t
- не что иное, как просто typedef, например int. Кажется, что sig_atomic_t sig
- это просто глобальная переменная.
Теперь я запуталась.
Правильно ли использовался мой код sig_atomic_t
? Если нет, не могли бы вы показать мне правильный пример? Если мой код правильный, что я неправильно понял? sig_atomic_t
это не глобальная переменная? Или глобальная переменная может использоваться в повторно входимой функции? Или функция sig_handler
может быть нереентерабельной функцией?