1

在我的应用程序(C++/Linux)中,有时一个线程在被取消时会获取一个互斥锁(递归)。这会导致死锁,因为其他线程也使用相同的互斥锁并且无法获得它。

现在可以检查该线程是否锁定了任何互斥体。我的动机是手动清除线程锁定然后取消线程。

我能想到的一种可能的方法是维护一个 counter 。任何更好的方法也将受到欢迎..

提前致谢

4

3 回答 3

4

许多库提供类似于 Windows 的TryEnterCriticalSection的机制。如果这返回一个表明互斥锁已被占用的信号,那么您就有了答案。

但是你有一个比这更大的问题。在正确设计的多代码应用程序中,您永远不会遇到死锁或竞争条件,并且您当然不必手动插入另一个线程来操纵它的状态。

您应该修复错误,而不是编写一些 hack。

于 2012-05-11T20:40:57.667 回答
1

一般来说,你应该避免使用pthread_cancel(),因为这样的问题。如果你必须使用它,你应该使用pthread_cleanup_push 和 pthread_cleanup_pop来保证如果线程被取消,互斥锁被解锁。

如果有人调用pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS),根本无法保证正确执行,所以不要那样做。

pthread_cancel()非常C-ish。考虑使用Boost 的线程中断,因为您使用 C++ 编程。这将与作用域锁定对象很好地组合。

于 2012-05-14T00:19:14.217 回答
0

正如约翰所说,主要问题是应用程序设计。

提示:在 C++ 中,在失败(抛出)的情况​​下唯一保证执行的是什么?析构函数。

您有 2 个选择:

  1. 您可以使用 C++11 或 boost lock_guard,它封装了一个普通的互斥锁,但提供了异常安全性,旨在避免像您这样的问题。但这意味着您需要将整个应用程序更改为使用 C++11 或 boost 线程,而不是 pthread。

  2. 您可以在析构函数中释放互斥锁。

祝你好运!

于 2012-05-12T17:08:57.580 回答