如果可能的话,有人请帮我解决c ++中的死锁问题,参考或示例。
情景如下所示。
Thread1被互斥锁定并执行某些操作,thread2和thread3处于等待状态,以便thread1解锁以访问资源。
发生了一些中止/意外的事情 - thread1被终止并且没有得到解锁,thread2和thread3仍在等待。
在这种情况下如何保存主线程(对主线程没有任何意义)。
请注意如何在c ++中解决此类问题。
谢谢, 谢赫
答案 0 :(得分:5)
发生了一些中止/意外事件
使用s.th.像std::lock_guard
一样,可以防止由于异常或遗忘/意外导致“挂起”锁定,但需要unlock()
次操作。
原理非常简单,您可以轻松地为任何使用一对以“锁定/解锁”方式对应的方法的机制实现它:
class LockObject // E.g. mutex or alike
{
public:
// ...
void lock();
void unlock();
};
将guard类构造函数绑定到对象的实例的引用,并在构造函数中调用lock()
并在析构函数中调用unlock()
:
template<typename T>
class LockGuard
{
public:
LockGuard(T& lockObject)
: lockObject_(lockObject)
{
lockObject_.lock();
}
~LockGuard()
{
lockObject_.unlock();
}
private:
T& lockObject_;
};
像这样使用LockGuard
:
// Some scope providing 'LockObject lockObject'
{ LockGuard<LockObject> lock(lockObject)
// Do s.th. when lockObject is locked
} // Call of lockObject.unlock() is guaranteed at least here, no matter what
// (exception, goto, break, etc.) caused leaving the block's scope.
答案 1 :(得分:2)
通常,线程不应意外终止。您可以尝试使用try / catch块。如果您仍希望在线程意外终止时释放资源,则可以创建一个等待第一个线程终止的监视器线程。
在Windows上,您可以使用:: WaitForSingleObject(m_htThread,INFINITE)。
第一个线程终止后,您可以继续释放废弃的锁。 也许你想要添加一些标志,表明终止是否优雅。 您可能还必须记住哪个线程正在锁定哪个对象。
如上所述,我不建议使用这种方法,但在极端情况下。
答案 2 :(得分:-1)
在任何语言或平台上解决死锁的方法总是一样的。
始终以相同的顺序获取锁。
编辑但是你错误地描述了你的问题。这不是僵局。死锁是一个循环的锁链。这只是一个未发布的锁,即锁泄漏。解决方案与任何其他资源泄漏相同:不要。在C ++中,这意味着在析构函数中释放资源,并确保调用析构函数。不知怎的,你的线程已经终止而没有这样做。找到那个问题并修复它。