开发者

Race condition in C signal handlers puzzle

开发者 https://www.devze.com 2023-01-22 21:14 出处:网络
I need to know how to avoid a race condition when handling signals in C. Each time my program receives a signal, I want it to alter a (global) linked list. It is vitally important that I not miss a si

I need to know how to avoid a race condition when handling signals in C. Each time my program receives a signal, I want it to alter a (global) linked list. It is vitally important that I not miss a signal, and equally important that the global linked list I'm modifying not be changed while the handler is executing.

The problem is, if I receive a signal, and start the handler, but am then interrupted by another signal. This (as I understand it) triggers a new execution of the si开发者_高级运维gnal handler, which will operate on the same global dataset - not permissible!

I can't use a lock, because if the first handler call is interrupted, it will naturally never free the lock for the interrupting handler to pick up. So, how do I do it? Any idea?


If you have the luck to be working in a multi-threaded environment, one of the best ways is to have the global linked list controlled exclusively by a separate thread. Interrupts would enqueue requests to this thread (something that would be executed very quickly, say, by simply passing a pointer), and then the thread would procedurally go through each request and modify the linked list. This allows lockless execution.

Of course, you have to rely on your OS's message passing junk, so that may not be an option.


You can mask signals while executing signal handler - check sa_mask field of struct sigaction you pass to sigaction() syscall.


From http://users.evtek.fi/~tk/rtp/signals-programming.html:

The way to guarantee no races at all, is to let the system set the signal masking for us before it calls the signal handler. This can be done if we use the sigaction() system call to define both the signal handler function AND the signal mask to be used when the handler is executed. You would probably be able to read the manual page for sigaction() on your own, now that you're familiar with the various concepts of signal handling. On old systems, however, you won't find this system call, but you still might find the sigvec() call, that enables a similar functionality.


I think you should seriate the signal.just like the work queue E.g. all the signal should put into a work queue(FIFO), and then the executing thread poll the queue all the time. if the queue is not empty,this thread will pick the top signal and start it`s handler. keep doing like that, until the queue is empty.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号