线程之间的信号

时间:2013-09-17 10:37:20

标签: c++ multithreading signaling

  

应用程序设计

我有一个c ++应用程序,它有一个生产者线程,多个队列(在运行时创建)和消费者线程。

生产者线程通过Tcp / Ip获取数据并放入相应的队列(例如,如果数据是类型A并放入队列A中)。

消费者线程当前从1-n循环队列以处理来自每个队列的数据。

根据要求,无需跟踪上次更新或最少更新的队列。只要更新了任何队列,消费者就应该处理1到n个队列。

如果任何队列的大小超过定义的限制,则生产者线程将在插入新项目之前弹出第一个项目(以管理队列大小)。

  

线程之间的资源同步和信令:

在此实现中,消费者线程应该休眠,直到没有队列具有来自侦听器的数据。只有当生产者将数据放入任何一个队列时,才会唤醒消费者线程。

使用互斥锁在2个线程之间同步多个队列。 在线程之间实现事件信令,以便在生产者将数据放入任何队列时唤醒消费者线程。

然而,这种信号唤醒消费者线程的方式,虽然任何队列中都有数据,但消费者可以睡觉。

  

问题:

让我们看看这个场景,考虑消费者正在处理第n个队列的数据;同时,生产者有可能将数据放入n-1,n-2队列,并且信令无效,因为消费者处于清醒状态并处理第n个数据。一旦消费者完成对第n个队列数据的处理,它就会休眠,并且在听众给出任何进一步的信号之前,n-1,n-2中的数据将不会被处理。

我们如何解决这个问题? 人们也建议使用半光团。信号量是否与这种情况相关?

提前致谢。

3 个答案:

答案 0 :(得分:3)

这是C ++ 11 std::condition_variable的经典示例。

这种情况下的条件是可消耗资源的可用性。如果消费者线程失去工作,他wait会在条件变量上有效地让他进入睡眠状态。每次插入队列后的生产者notify。必须注意以尽可能减少队列争用的方式安排锁定,同时仍然避免消费者错过通知并进入睡眠状态,尽管工作可用。

答案 1 :(得分:1)

信号量会起作用,是的。

但我不确定是否有必要。听起来你的问题纯粹是因为消费者线程在处理队列N之后无法循环回来。它应该在它连续看到N 队列后才会进入休眠状态,同时持有互斥锁以确保平均时间内没有添加任何条目。

当然,持有该互斥量一直是矫枉过正的。相反,您应该保持循环,逐个清空队列并计算您看到的空队列数。一旦您连续看到N个空队列,请使用互斥锁,这样您就不会添加任何新条目,现在重新检查。

这取决于您的信号机制。强大的信号机制允许您在线程进入该信号的检查之前发出信号。这是必要的,因为否则你有竞争条件。

答案 2 :(得分:0)

您可以使用select并在信号 - >>的文件描述符上等待它所以它可以等待超时(选择它们)并在接收到信号时唤醒(信号必须被屏蔽和阻止)。当signalfd(外观man signalfd)可读时,您可以从中读取struct signalfd_siginfo并检查ssi_signo的信号编号(如果它是您用于通信的那个)。 / p>