C信号处理程序拼图中的竞争条件

时间:2010-11-02 11:25:37

标签: c event-handling signals race-condition

我需要知道在C中处理信号时如何避免竞争条件。每当我的程序收到信号时,我希望它改变(全局)链表。至关重要的是,我不会错过任何信号,同样重要的是我正在修改的全局链表在执行处理程序时不会被更改。

问题是,如果我收到信号,并启动处理程序,但然后被另一个信号打断。这(据我所知)触发了信号处理程序的新执行,它将在相同的全局数据集上运行 - 不允许!

我不能使用锁,因为如果第一个处理程序调用被中断,它自然永远不会释放锁以让中断处理程序获取。那么,我该怎么做?有什么想法吗?

4 个答案:

答案 0 :(得分:1)

如果您有幸在多线程环境中工作,最好的方法之一是让全局链表完全由一个单独的线程控制。中断会将请求排入此线程(例如,通过简单地传递指针就可以非常快速地执行),然后线程将在程序上遍历每个请求并修改链接列表。这允许无锁执行。

当然,你必须依靠你的操作系统的消息传递垃圾,所以这可能不是一个选项。

答案 1 :(得分:1)

您可以在执行信号处理程序时屏蔽信号 - 检查sa_mask传递给struct sigaction系统调用的sigaction()字段。

答案 2 :(得分:1)

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

保证不参加比赛的方法是让系统在调用信号处理程序之前为我们设置信号屏蔽。如果我们使用sigaction()系统调用来定义信号处理函数和执行处理程序时要使用的信号掩码,则可以执行此操作。您可能已经能够自己阅读sigaction()的手册页,因为您已熟悉信号处理的各种概念。但是,在旧系统上,您将找不到此系统调用,但仍然可以找到sigvec()调用,它启用了类似的功能。

答案 3 :(得分:0)

我认为你应该将信号序列化。就像工作队列一样 例如。所有信号都应该放入工作队列(FIFO),然后执行线程一直轮询队列。如果队列不为空,则该线程将选择顶部信号并启动它的处理程序。继续这样做,直到队列为空。