在我的应用程序(C++/Linux)中,有时一个线程在被取消时会获取一个互斥锁(递归)。这会导致死锁,因为其他线程也使用相同的互斥锁并且无法获得它。
现在可以检查该线程是否锁定了任何互斥体。我的动机是手动清除线程锁定然后取消线程。
我能想到的一种可能的方法是维护一个 counter 。任何更好的方法也将受到欢迎..
提前致谢
在我的应用程序(C++/Linux)中,有时一个线程在被取消时会获取一个互斥锁(递归)。这会导致死锁,因为其他线程也使用相同的互斥锁并且无法获得它。
现在可以检查该线程是否锁定了任何互斥体。我的动机是手动清除线程锁定然后取消线程。
我能想到的一种可能的方法是维护一个 counter 。任何更好的方法也将受到欢迎..
提前致谢
许多库提供类似于 Windows 的TryEnterCriticalSection的机制。如果这返回一个表明互斥锁已被占用的信号,那么您就有了答案。
但是你有一个比这更大的问题。在正确设计的多代码应用程序中,您永远不会遇到死锁或竞争条件,并且您当然不必手动插入另一个线程来操纵它的状态。
您应该修复错误,而不是编写一些 hack。
一般来说,你应该避免使用pthread_cancel()
,因为这样的问题。如果你必须使用它,你应该使用pthread_cleanup_push 和 pthread_cleanup_pop来保证如果线程被取消,互斥锁被解锁。
如果有人调用pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS)
,根本无法保证正确执行,所以不要那样做。
pthread_cancel()
非常C-ish。考虑使用Boost 的线程中断,因为您使用 C++ 编程。这将与作用域锁定对象很好地组合。
正如约翰所说,主要问题是应用程序设计。
提示:在 C++ 中,在失败(抛出)的情况下唯一保证执行的是什么?析构函数。
您有 2 个选择:
您可以使用 C++11 或 boost lock_guard,它封装了一个普通的互斥锁,但提供了异常安全性,旨在避免像您这样的问题。但这意味着您需要将整个应用程序更改为使用 C++11 或 boost 线程,而不是 pthread。
您可以在析构函数中释放互斥锁。
祝你好运!