Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何解决C++; 如果有可能的话,请帮助我解决C++中的死锁问题。_C++_Multithreading - Fatal编程技术网

如何解决C++; 如果有可能的话,请帮助我解决C++中的死锁问题。

如何解决C++; 如果有可能的话,请帮助我解决C++中的死锁问题。,c++,multithreading,C++,Multithreading,场景如下所示 线程1已被互斥锁锁定,在执行某些操作时,线程2和线程3处于等待状态,等待线程1解锁以访问资源 发生了一些中止/意外事件--thread1已终止,未获得解锁,thread2和thread3仍在等待 在这种情况下如何保存主线程(意味着主线程不会发生任何事情) 请在C++中解决一些问题。 谢谢, 酋长 发生了一些意外的事情 使用s.th。喜欢防止由于异常或遗忘/意外但必要的unlock()操作而“挂起”锁 原理非常简单,您可以轻松地将其应用于任何使用一对方法的机制,这些方法以“锁定/解锁

场景如下所示

线程1已被互斥锁锁定,在执行某些操作时,线程2和线程3处于等待状态,等待线程1解锁以访问资源

发生了一些中止/意外事件--thread1已终止,未获得解锁,thread2和thread3仍在等待

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

请在C++中解决一些问题。 谢谢, 酋长

发生了一些意外的事情

使用s.th。喜欢防止由于异常或遗忘/意外但必要的
unlock()
操作而“挂起”锁

原理非常简单,您可以轻松地将其应用于任何使用一对方法的机制,这些方法以“锁定/解锁”方式相互对应:

class LockObject // E.g. mutex or alike
{
public:
    // ...
    void lock();
    void unlock();
};
将guard classes构造函数绑定到锁对象实例的引用,并在构造函数中调用
lock()
,在析构函数中调用
unlock()

template<typename T>
class LockGuard
{
public:
    LockGuard(T& lockObject)
    : lockObject_(lockObject) 
    {
        lockObject_.lock();
    }
    ~LockGuard()
    {
        lockObject_.unlock();
    }

private:
    T& lockObject_;
};

在任何语言或平台中解决死锁的方法都是一样的

始终以相同的顺序获取锁


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

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

在Windows上,可以使用::WaitForSingleObject(m_htThread,INFINITE)之类的东西

第一个线程终止后,您可以继续释放放弃的锁。 也许您需要添加一些标志,指示终止是否优雅。 您可能还需要记住哪个线程正在锁定哪个对象


正如我所说,我不建议使用这种方法,但是在极端情况下,

你能显示一些代码来说明你如何使用C++中的线程吗?你说的“保存主线程”是什么意思?展示一个小的、可编译的代码示例将非常有帮助。为什么会有反对票??这是一个有价值且严肃的问题(可能超出了下层选民的想象)!这不是僵局。死锁是一个循环锁链。这只是一个未释放的锁,即锁泄漏。解决方案与任何其他资源泄漏都是一样的。修复线程1怎么样?但他的问题是有一个锁没有被释放,而不是他以错误的顺序获取了第二个锁。因此,在这种情况下,这不是正确的解决方案。无论是谁否决了这一点:这完全正确,但可能与OP描述的情况不符(我认为这是更简单的原因)。@g-makulik显然这是一个正确的说法,但与OP问题无关。任何没有解决这个问题的答案都会被否决。在这个场景中只有一个锁。@RyanHaining'但它与OPs问题“是”无关!你说得对!但无论如何,我认为这不值得一票否决。这是正确处理死锁的一个重要方面(至少在问题标题中提到了这一点),可能会给OP带来启发;o) …@WanderingLogic在这种情况下,问题根本不是死锁。但是,如果线程处于死锁状态,是否会调用析构函数killed@RyanHaining如果s.th。像一个
thread::kill()
操作是可用的(特定于操作系统?),我希望它能正确地展开堆栈@RyanHaining从外部杀死线程在C/C++中是一个相当糟糕的主意。首先,C++11的线程API不允许这样做是有原因的。终止线程的正确方法是实现一种机制来发出终止请求的信号,然后允许线程自行关闭。@ComicSanms我知道终止线程是一件可怕的事情,尽管如此,我认为问题是,如果线程在持有互斥锁时被终止,有办法解锁它吗?。这仍然是一个可靠的答案
// 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.