我想问您一个问题,关于我应该选择哪种并发工具(CMutex、CSemaphore、CEvent)来使 C++/MFC 应用程序成为多线程。
它是一个实时机器视觉应用程序,现在需要并发执行,并且需要从之前的单线程状态进行重构。
我的工作流程的一次迭代如下。我有 2 个生产者 A、B(MFC Workers),需要填充两个单独的数据结构(各 1 个)。第三个线程,消费者(也是 MFC Worker)被阻塞,直到 A 和 B 的两个数据都可用。然后,生产者 A 和 B 必须阻塞(每个线程在数据完成时),C必须醒来,执行计算,解锁 A 和 B 才能继续,然后再次阻塞,等待下一个段。
- 我不能使用队列(类似于 Actor) - 阻塞是一个要求 :(
- 我尝试了 CEvent 并且它有效。 A、B 的 AutoResetEvents 解锁 a CMultiLock 调用 C,然后从 C 调用 ManualResetEvent->Set(),以 解锁 A 和 B 等待后一个事件。我关心的是何时 重置此事件(例如,如果 A 错过整个 Set,然后重置。)
- 多个 2 的信号量是否可以代表更好的解决方案?
致以诚挚的问候。
最佳答案
C 必须等待两件事发生,因此最合乎逻辑的事情是它等待两个自动重置 CEvent
对象:一个由 A 设置,另一个由 B 设置。
当 C 完成后,A 和 B 必须各自等待通知。由于有两个线程,并且都必须唤醒,因此很自然的事情是使用另一对自动重置 CEvent
对象,A 和 B 各一个。然后,C 可以在它被唤醒时设置这两个线程。完成。
计数为 2 的信号量可用于唤醒 C --- C 等待两次,并且 A 和 B 各自通知 --- 但这意味着 C 必须在第一次通知后唤醒,以便等待第二,不太理想。
之后使用计数为 2 的信号量唤醒 A 和 B 可能会导致被盗唤醒和困惑。 C 向信号量发出两次信号。 A 醒来并获取信号,进行处理并通知 C,然后再次等待信号量。由于B还没有醒来,信号量仍然可用,所以A再次拿走它。同时 B 没有被卡住,因为它不会收到另一个信号,而 C 被卡住,因为它将等待来自 B 的下一个值。
另一种方法是使用 Windows 条件变量 API 而不是事件,但似乎没有 MFC 包装器。请参阅http://msdn.microsoft.com/en-us/library/ms682052%28VS.85%29.aspx
关于c++ - 我应该选择什么同步方案来避免实时 C++/MFC 应用程序上的死锁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7664561/