1

我正在用 C++ 编写线程安全的类。它的所有公共方法都使用锁(非递归自旋锁). 私有方法是无锁的。所以,一切都应该没问题:用户调用公共方法,它锁定对象,然后通过私有方法完成工作。但是当一个公共方法调用另一个公共方法时,我得到了死锁。我读过递归互斥锁很糟糕,因为很难调试它们。所以我使用 C 的 stdio 方式:公共方法 Foo() 只锁定对象并调用 Foo_nolock() 来完成整个工作。但我不喜欢这些 _nolock() 方法。我认为它复制了我的代码。所以我有了一个想法:我将创建无锁类 BarNoLock,以及只有一个成员的线程安全类 Bar:BarNoLock 的一个实例。并且所有 Bar 的方法只会锁定这个成员并调用它的方法。这是一个好主意还是有一些更好的模式/实践?谢谢。更新:我知道 pimpl 和 bridge。

4

2 回答 2

1

看起来您已经重新发明了Bridge Pattern。听起来井井有条。

于 2010-08-16T17:23:01.373 回答
1

我不确定为什么递归互斥锁会被认为是不好的,请参阅此问题以讨论它们。

递归锁(互斥锁)与非递归锁(互斥锁)

但我认为这不一定是您的问题,因为 Win32 关键部分支持来自同一线程的多个条目而不会阻塞。从文档

当线程拥有临界区时,它可以对 EnterCriticalSection 或 TryEnterCriticalSection 进行额外调用,而不会阻止其执行。这可以防止线程在等待它已经拥有的临界区时自行死锁。要释放其所有权,线程必须在每次进入临界区时调用一次 LeaveCriticalSection。无法保证等待线程获取临界区所有权的顺序

所以当你陷入僵局时,也许你做错了什么?必须解决不使用奇怪的函数调用语义在同一个线程的同一个互斥锁上死锁的问题,这不是您应该做的事情。

于 2010-08-16T17:27:53.693 回答