如何解决C ++中未发布的锁定问题

时间:2013-07-20 01:54:08

标签: c++ multithreading

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

情景如下所示。

Thread1被互斥锁定并执行某些操作,thread2和thread3处于等待状态,以便thread1解锁以访问资源。

发生了一些中止/意外的事情 - thread1被终止并且没有得到解锁,thread2和thread3仍在等待。

在这种情况下如何保存主线程(对主线程没有任何意义)。

请注意如何在c ++中解决此类问题。

谢谢, 谢赫

3 个答案:

答案 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 ++中,这意味着在析构函数中释放资源,并确保调用析构函数。不知怎的,你的线程已经终止而没有这样做。找到那个问题并修复它。