Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
通过组合向类添加锁 我在C++中编写线程安全类。它的所有公共方法都使用锁(非递归旋转锁)。私有方法是无锁的。所以,一切都应该正常:用户调用public方法,它锁定对象,然后通过私有方法执行工作。但是当一个公共方法调用另一个公共方法时,我就死锁了。我读到过递归互斥是不好的,因为很难调试它们。所以我使用C的stdio方式:public方法Foo()只锁定对象并调用Foo_nolock()来完成整个工作。但我不喜欢这些_nolock()方法。我想它复制了我的代码。 所以我有了一个想法:我将创建无锁类BarNoLock和线程安全类Bar,它们只有一个成员:BarNoLock的一个实例。所有的Bar方法只会锁定这个成员并调用它的方法。 这是个好主意还是有更好的模式/实践?谢谢 更新:我知道pimpl和bridge。我问的是多线程模式,而不是OOP。_C++_Multithreading_Locks - Fatal编程技术网

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

通过组合向类添加锁 我在C++中编写线程安全类。它的所有公共方法都使用锁(非递归旋转锁)。私有方法是无锁的。所以,一切都应该正常:用户调用public方法,它锁定对象,然后通过私有方法执行工作。但是当一个公共方法调用另一个公共方法时,我就死锁了。我读到过递归互斥是不好的,因为很难调试它们。所以我使用C的stdio方式:public方法Foo()只锁定对象并调用Foo_nolock()来完成整个工作。但我不喜欢这些_nolock()方法。我想它复制了我的代码。 所以我有了一个想法:我将创建无锁类BarNoLock和线程安全类Bar,它们只有一个成员:BarNoLock的一个实例。所有的Bar方法只会锁定这个成员并调用它的方法。 这是个好主意还是有更好的模式/实践?谢谢 更新:我知道pimpl和bridge。我问的是多线程模式,而不是OOP。,c++,multithreading,locks,C++,Multithreading,Locks,看起来您已经重新发明了多线程模式。听起来很正常。我不知道为什么递归互斥会被认为是不好的,关于它们的讨论,请参阅这个问题 但我认为这不一定是您的问题,因为Win32关键部分支持来自同一线程的多个条目而不阻塞。从: 当线程拥有关键部分时,它可以对EnterCriticalSection或TryEnterCriticalSection进行额外调用,而不会阻止其执行。这可以防止线程在等待它已经拥有的关键部分时自行死锁。要释放其所有权,线程必须在每次进入关键部分时调用LeaveCriticalSecti

看起来您已经重新发明了多线程模式。听起来很正常。

我不知道为什么递归互斥会被认为是不好的,关于它们的讨论,请参阅这个问题

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

当线程拥有关键部分时,它可以对EnterCriticalSection或TryEnterCriticalSection进行额外调用,而不会阻止其执行。这可以防止线程在等待它已经拥有的关键部分时自行死锁。要释放其所有权,线程必须在每次进入关键部分时调用LeaveCriticalSection一次。对于等待的线程获取关键部分所有权的顺序没有保证
所以当你把自己锁死的时候,也许你做错了什么?您不必解决使用奇怪的函数调用语义在同一线程的同一互斥锁上死锁的问题。

您是对的,CS是递归的。我的应用程序在实践中并没有死锁,只是在理论上。但是我不想使用递归锁。如果你坚决反对递归锁,那么你的建议听起来是合理的。我想说的另一件事是,只有当对象的一个公共函数调用另一个公共函数时,您的原始设计才会出现问题。显而易见的解决办法就是不要这样做,只要你有需要共享的共享功能,就把它分解成一个私有的非锁定方法。然后,每个公共方法都会拉锁并执行其工作,而使用的私有方法不会拉锁。BShiels:那么,你建议我将所有公共方法的功能都放在无锁私有方法中:Foo()->Foo_nolock()?这是一个原始的设计,Foo_nolock()等应该没问题-我看不出你是如何得到你担心的代码重复的。如何使_nolock变量重复代码,但Bar/BarNoLock没有?只是_nolock方法现在在BarNoLock。不过,我想我还是走酒吧/巴诺洛克路线,使用pimpl成语。BarNoLock那时将成为Bar的一个私有内部类。这就是我所说的——bridge或pimpl,是的。我问的是多线程习惯用法,而不是OOP