I've been developing C++ on Linux for a long time. And when I develop some independent module processing a message/task queue, I always process the SIGINT
signal to avoid message/task loss. Here is an example of my code:
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;
}
Well, this piece of code is simple: if the signal SIGINT
is captured, stop receiving messages, process all of messages left in the queue and return. Otherwise, the code will stay in the infinite while.
I thought the sig_atomic_t
was some black magic. Because as my understanding, the function sig_handler
must be a reentrant function, meaning that it can't hold any static or global non-constant data: What exactly is a reentrant function?
So I always thought that sig_atomic_t
was some tricky stuff, instead of a global variable.
But today I read this link: How does sig_atomic_t actually work?, which told me that sig_atomic_t
is nothing but simply a typedef, such as an int. So it seems that sig_atomic_t sig
is simply a global variable.
Now I'm confused.
Did my code above use sig_atomic_t
correctly? If not, could you please show me a correct example? If my code is correct, what did I misunderstand? sig_atomic_t
is not a global varible? Or a global variable can be used in a reentrant function? Or the function sig_handler
can be non-reentrant function?