我有一个关于线程间通信的一般性问题。
现在我正在使用一堆C ++线程(~15)。
他们都在使用BusyWait(轮询)来获取要处理的数据。但很难保持低CPU和低频率。提供良好的性能并避免进行太多的上下文切换。
所以我看着Condition变量和信号。我想我理解让线程进入.Wait()的一般概念,等待另一个线程调用.Signal()。
问题#1)我的问题可能是概念性的,但是如果等待信号的线程在等待时变为SUSPENDED,则它自己无法执行任何操作。无论如何,让它自己醒来去做一些行动。
问题#2)此外,我的班级用于向两个方向传递数据。但是如果中产阶级正在等待来自另一个类的信号,则它无法向该类发送信号。如:
_________ _________ __________
| Class A |---newData Signal--->| Class B |---newData Signal--->| Class C |
| | |(WAITING)|<---newData Signal---| |
--------- --------- ----------
因此,如果B类在C上打开.Signal()的.Wait(),则无法处理来自A的新信号。
A&amp;&amp; A&amp;是否可能C发送相同的“newData”信号B来唤醒它?是否有可能区分A&amp; amp;的信号?下进行。
我正在使用C ++编写这个使用ACE框架&amp; amp;可能会切换到Boost。但我想这很通用,我可以将答案应用到任何操作系统(希望如此)。
由于
答案 0 :(得分:2)
如果您希望父线程在子线程运行时工作,您可以等待超时信号。每次超时到期时,您都会做一些工作并再次等待。
答案 1 :(得分:1)
问题#1)在大多数实现中,你可以限制最长等待时间,所以说:等待2秒,然后做一些事情再等一下。
问题#2)在大多数实现中,您可以一次等待多个信号。您可以说:如果触发信号A或B,则唤醒。
答案 2 :(得分:0)
你寻求的答案非常复杂,这个维基上的空间并不足以解决所有问题:(
您需要做的是找到一些好的网站,提供有关线程如何工作的解释。您所追求的大部分内容都可以通过正确的设计完成,但您需要首先更好地理解这些概念。
为了让您的通信得以解决,您需要将信号发送到正确的位置并等待正确的事件。
执行此操作的最简单方法是使用比轮询更好的方法是使用所有线程共享的单个条件变量。当这个状况发出信号时,他们都会醒来并寻找一些工作要做。
这不是很有效,但很简单,对您有用,并且比轮询更有效。一旦你有了这个工作,你可以尝试引入一些新的条件变量并分割哪些线程等待哪些 - 当这样做时你会犯很多错误并经历许多死锁和星球。坚持不懈,你会开始明白这一切是如何运作的。
祝你好运。答案 3 :(得分:0)
虽然您可以为此使用条件变量,但问题描述建议使用消息队列。然后,线程A和线程C可以将消息注入B的队列,并且B相应地处理它们。 (当然,要区分这两个线程,您应该安排A和C发送不同的消息。)
我不知道ACE对消息队列有什么支持,但是,在Java并发框架中,您可以使用ConcurrentLinkedQueue
构建自己的穷人消息队列。 : - )
答案 4 :(得分:0)
假设您有某种方法可以执行关键部分锁定(例如java synchronized)或线程安全队列,您可以使用运行队列。
对于每个线程,修改/覆盖睡眠实现,以便在线程等待时,它将自己添加到运行队列的末尾。
假设一次只运行一个线程,当前运行的线程在它自己进入休眠/等待之前应该做的最后一件事是唤醒列表头部的线程。
如果您需要更复杂的线程执行/调度,下一步是创建一个调度程序线程,该线程遍历队列,调整队列中线程的顺序,检查哪个线程具有所需的所有资源。跑等等。