如果可能的话,请有人通过参考或示例帮助我解决 C++ 中的死锁问题。
场景如下所示。
线程 1 被互斥锁锁定并做一些操作,线程 2 和线程 3 处于等待线程 1 解锁访问资源的状态。
发生了一些中止/意外的事情——线程 1 被终止并且没有获得解锁,线程 2 和线程 3 仍在等待。
在这种情况下如何保存主线程(意味着主线程不应该发生任何事情)。
请说明如何在 C++ 中解决此类问题。
谢谢,谢赫
如果可能的话,请有人通过参考或示例帮助我解决 C++ 中的死锁问题。
场景如下所示。
线程 1 被互斥锁锁定并做一些操作,线程 2 和线程 3 处于等待线程 1 解锁访问资源的状态。
发生了一些中止/意外的事情——线程 1 被终止并且没有获得解锁,线程 2 和线程 3 仍在等待。
在这种情况下如何保存主线程(意味着主线程不应该发生任何事情)。
请说明如何在 C++ 中解决此类问题。
谢谢,谢赫
发生了一些中止/意外的事情
使用某物 喜欢std::lock_guard
防止由于异常或忘记/意外但必要的unlock()
操作而导致“挂起”锁。
原理非常简单,您可以轻松地为任何使用一对以“锁定/解锁”方式对应的方法的机制实现它:
class LockObject // E.g. mutex or alike
{
public:
// ...
void lock();
void unlock();
};
将保护类构造函数绑定到对锁对象实例的引用,并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.
通常线程不应意外终止。您可以尝试使用 try/catch 块。如果您在线程意外终止时仍想释放资源,您可以创建一个等待第一个线程终止的监视器线程。
在 Windows 上,您可以使用 ::WaitForSingleObject(m_htThread, INFINITE)。
一旦第一个线程被终止,您可以继续释放废弃的锁。也许您会想要添加一些标志来指示终止是否正常。您可能还必须记住哪个线程正在锁定哪个对象。
如前所述,我不建议使用这种方法,但在极端情况下。
任何语言或平台解决死锁的方法总是相同的。
始终以相同的顺序获取锁。
编辑:但是您错误地描述了您的问题。这不是僵局。死锁是一个循环的锁链。这只是一个未释放的锁,即锁泄漏。解决方案与任何其他资源泄漏相同:不要。在 C++ 中,这意味着在析构函数中释放资源,并确保调用析构函数。不知何故,您的线程在没有这样做的情况下终止了。找到那个问题并解决它。