使用 MFC 同步对象的陷阱
Posted
技术标签:
【中文标题】使用 MFC 同步对象的陷阱【英文标题】:Pitfalls on using MFC Synchronization Objects 【发布时间】:2011-08-22 07:37:33 【问题描述】:我在我的项目中使用了 MFC 同步对象,没有任何问题。但最近我看到一篇文章,解释了MFC synchronization is completely wrong。我不确定他说的是哪个版本的 MFC,但我坚信 MFC 在最近的版本中已经成熟。我正在使用随 Visual Studio 2008 安装一起提供的 MFC 库。使用此版本的 MFC 库(尤其是用于同步)是否安全?
【问题讨论】:
读完那篇文章...我不会冒险的。这不值得,只是为了一些围绕 Win32 同步原语的小型 OOP 包装器。最好只使用一个可能不是由猴子敲击键盘构建的线程库。 但我想使用 RAII 来避免资源泄漏。否则我必须自己去包装。 或者你可以使用Boost.Thread。或TBB。或PPL。或者任何数量的具有 RAII 的 C++ 库。或者花 10 分钟将 Win32 的同步原语包装在对象中。 【参考方案1】:关于互斥超时,有一个并发软件设计学派说您不应该在正常操作中使用超时。然后,您的设计将涉及永远不会超时的互斥锁或其他锁,而超时实际上是一种处理死锁的机制:您尝试将系统设计为不出现死锁,但如果它们确实发生,您宁愿拥有它或多或少优雅地失败,而不是永远保持解除锁定状态。
如果您以这种方式使用锁,那么尝试获取互斥锁失败的原因可能并不重要。
另一方面,它似乎并没有从根本上被破坏,但至少有些不足,即这些信息无缘无故丢失,并且有更好的框架为互斥锁提供 OO 包装器,所以不管这避免了 MFC这个案例似乎是个好主意。
【讨论】:
【参考方案2】:作者的断言并不适用于所有条件,而是适用于特定的一组条件。 Lock
返回 BOOL,如果它由于某种原因而失败,您通常不会在意。大多数时候你会打电话来获取锁或等待。在其他情况下,FALSE 意味着失败。如果需要检查超时,可以使用原生 API(这种情况很少见)。
递归CSingleLock
是荒谬的。您不使用 same 对象重新锁定。您可以安全地使用多个 CSinlgeLock
对象来获得递归访问。
CEvent
、CMutex
和其他命名对象类可以跨进程使用。我用过!
我不使用信号量。可能其他人可以发表评论。
【讨论】:
如果Lock
没有区分“互斥锁空闲”、“超时触发”、“最后一个互斥锁持有者在持有它时死亡”和“错误”,然后Lock
坏了。你不能相信它,因为有些情况你需要处理。至少,您不能使用实际的超时,除非您能分辨出合法发布和超时之间的区别。
不过,您对他对 CSingleLock 的评估是正确的。我的意思是,它就在标题中:SINGLELock。以上是关于使用 MFC 同步对象的陷阱的主要内容,如果未能解决你的问题,请参考以下文章
NIO框架之MINA源码解析:NIO超级陷阱和使用同步IO与MINA通信