我想问一个关于应该选择哪种并发工具(CMutex,CSemaphore,CEvent)的问题,以使C ++ / MFC应用程序成为多线程。
这是一个实时的机器视觉应用程序,现在需要同时执行,并且需要重构,从之前的单线程状态开始。
我的工作流程的单次迭代如下。我有2个生产者A,B(MFC工人)需要填充两个独立的数据结构(每个1个)。第三个线程,消费者(MFC工作者也被阻止),直到两个数据从A和B可用。然后,生产者A和B必须阻止(每个,在数据完成时),C必须醒来,执行计算,取消阻止A和B继续并再次被阻止,等待下一段。
最好的问候。
答案 0 :(得分:2)
我会稍微修改你的选项2 - 在两个事件上使用CMultiLock来阻止C;然后使用另一个对事件来阻止A和B.C会设置两个自动重置事件来唤醒A和B中的每一个。然后你不再参加比赛重置。
答案 1 :(得分:2)
C必须等待两件事情发生,所以最合乎逻辑的是它等待两个自动重置CEvent
个对象:一个由A设置,另一个由B设置。
当C完成时,A和B必须各自等待通知。由于有两个线程,并且两个线程都必须唤醒,所以自然就是使用另一对自动重置CEvent
对象,每个对象分别对应A和B.然后,C可以在完成时设置它们。 / p>
计数为2的信号量可用于唤醒C --- C等待两次,A和B中的每一个都通知---但这意味着C必须在第一次通知后醒来才能等待第二,这不太理想。
使用计数为2的信号量来唤醒A和B后,可能会导致被唤醒和混乱。 C两次发信号通知信号量。唤醒并接收信号,进行处理并通知C,然后再次等待信号量。由于B尚未唤醒,信号量仍然可用,所以A再次接受它。同时B没有卡住,因为它不会得到另一个信号,而C卡住了,因为它会等待B的下一个值。
另一种方法是使用Windows条件变量API而不是事件,但似乎没有MFC包装器。见http://msdn.microsoft.com/en-us/library/ms682052%28VS.85%29.aspx
答案 2 :(得分:0)
我建议使用由互斥锁保护的计数器的信号系统。这使得所有同步工作都局限于一个没有其他的小类。
A starts
A writes A-Data
A signals
A stops
B starts
B writes B-Data
B signals
B stops
C starts
C reads A-Data and B-Data
C starts A, B
C stops
*Signal Class*
Mutex protected counter attribute
Receives signal for A, increment counter
Receives signal for B, increment counter
IF counter equals 2, clear counter and start C
答案 3 :(得分:0)
你可以简单地使用CEvent对象而不是WaitForMultipleObjects(),它允许你通过第三个参数'bWaitAll'等待两个对象。
http://msdn.microsoft.com/en-us/library/windows/desktop/ms687025%28v=vs.85%29.aspx