2

如果可能的话,请有人通过参考或示例帮助我解决 C++ 中的死锁问题。

场景如下所示。

线程 1 被互斥锁锁定并做一些操作,线程 2 和线程 3 处于等待线程 1 解锁访问资源的状态。

发生了一些中止/意外的事情——线程 1 被终止并且没有获得解锁,线程 2 和线程 3 仍在等待。

在这种情况下如何保存主线程(意味着主线程不应该发生任何事情)。

请说明如何在 C++ 中解决此类问题。

谢谢,谢赫

4

3 回答 3

5

发生了一些中止/意外的事情

使用某物 喜欢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.
于 2013-07-20T02:01:25.450 回答
2

通常线程不应意外终止。您可以尝试使用 try/catch 块。如果您在线程意外终止时仍想释放资源,您可以创建一个等待第一个线程终止的监视器线程。

在 Windows 上,您可以使用 ::WaitForSingleObject(m_htThread, INFINITE)。

一旦第一个线程被终止,您可以继续释放废弃的锁。也许您会想要添加一些标志来指示终止是否正常。您可能还必须记住哪个线程正在锁定哪个对象。

如前所述,我不建议使用这种方法,但在极端情况下。

于 2013-07-20T07:58:01.790 回答
-1

任何语言或平台解决死锁的方法总是相同的。

始终以相同的顺序获取锁。

编辑:但是您错误地描述了您的问题。这不是僵局。死锁是一个循环的锁链。这只是一个未释放的锁,即锁泄漏。解决方案与任何其他资源泄漏相同:不要。在 C++ 中,这意味着在析构函数中释放资源,并确保调用析构函数。不知何故,您的线程在没有这样做的情况下终止了。找到那个问题并解决它。

于 2013-07-20T02:35:28.810 回答