草庐IT

Linux产生死锁的必要条件和常见的锁种类

目录前言产生死锁的4个必要条件预防(解决)死锁Linux常见的锁互斥锁(普通锁)自旋锁互斥锁和自旋锁小结递归锁读写锁乐观锁与悲观锁乐观锁和悲观锁小结其他锁(了解)前言之前面试的时候,有面试官问我产生死锁的(4个)必要条件,这个我之前有了解过,但是当时觉得这些必要条件很官方,也就没有重视,最后答得支支吾吾,面试官笑着说下去去可以看看,这个在面试中跟智能指针一样还挺常见的;(面试全程都很顺利,卡在这个简单的问题上确实不应该)由此面试碰到了让我介绍linux下mutex的种类,这个也是之前略知一二,但是详细场景和机制还是欠缺;这篇博客根据上面两个面试中出现的问题,以本人个人理解进行总结:产生死锁的4

c++ - 创建原子引用计数的尝试因死锁而失败。这是正确的方法吗?

所以我正在尝试创建写时复制映射,它在读取端尝试使用原子引用计数来避免锁定。有点不对劲。我看到一些引用变得过度增加,而有些则下降为负值,所以有些东西并不是真正的原子。在我的测试中,我有10个读取器线程循环100次,每个线程执行get()和1个写入器线程执行100次写入。它卡在了writer中,因为一些引用永远不会归零,即使它们应该归零。我正在尝试使用铺设的128位DCAS技术explainedbythisblog.这是否有明显的错误,或者是否有更简单的方法来调试它而不是在调试器中使用它?typedefstd::unordered_mapStringMap;staticconstintze

C++17 原子和 condition_variable 死锁

我有以下代码,它在注释行上死锁。基本上f1和f2在程序中作为单独的线程运行。f1期望i为1并递减它,通知cv。f2期望i为0并递增它,通知cv。我假设如果f2将i递增到1会发生死锁,调用cv.notify(),然后f1读取i的陈旧值(即0),因为互斥锁和i之间没有内存同步,然后等待并且永远不会被唤醒向上。然后f2也进入休眠状态,现在两个线程都在等待一个永远不会被通知的cv。如何编写这段代码才不会发生死锁?基本上我想要实现的是拥有一些由两个线程更新的原子状态。如果其中一个线程的状态不正确,我不想旋转;相反,我想使用cv功能(或类似功能)在值正确时唤醒线程。我正在使用g++-7与O3一起编

c++ - std::thread.join() 死锁

我不明白为什么这个简单的片段有一个死锁:#include#include#includeusingnamespacestd;classTest{public:Test():mExit(false){mThread=thread(bind(&Test::func,this));}~Test(){if(mThread.joinable()){mExit=true;mThread.join();}}private:voidfunc(){while(!mExit){//dosomething}}private:atomicmExit;threadmThread;};typedefunique_

c++ - 获取两个互斥量的锁并避免死锁

以下代码包含潜在的死锁,但似乎是必要的:要将数据从一个容器安全地复制到另一个容器,必须锁定两个容器以防止在另一个线程中发生更改。voidfoo::copy(constfoo&rhs){pMutex->lock();rhs.pMutex->lock();//docopy}Foo有一个STL容器,“复制”本质上就是使用std::copy。如何在不引入死锁的情况下锁定两个互斥量? 最佳答案 对foo实例施加某种总顺序,并始终以递增或递减顺序获取它们的锁,例如,foo1->lock()然后是foo2->lock()。另一种方法是使用函数语义

c++ - 使用 OpenMP 和 Eigen 会导致无限循环/死锁

我正在解决一个更大的问题,并且在尝试使用OpenMP并行化某些循环时遇到了错误。我用下面一些模仿我自己的代码的更简单的代码重现了这个问题。问题是当我运行程序时,它会随机进入某种无限循环/死锁(CPU是100%,但什么都不做)。从我的测试中可以看出,其中一个线程尝试计算矩阵矩阵乘积,但由于某种原因从未完成。我知道如果启用OpenMP,Eigen将使用OpenMP并行化矩阵-矩阵乘积。我还在这之外添加了另一个并行循环。但是,如果我通过定义EIGEN_DONT_PARALLELIZE禁用Eigen的并行化,这个错误仍然会发生。我在带有Eigen3.0.4的MacOS10.6.8上使用gcc版

windows - 是否可以推进死锁线程?卡在 WaitForSingleObject

如果我有一个正在创建线程的应用程序,这些线程完成它们的工作然后退出,并且一个或多个线程使自己陷入死锁(可能不是我自己的错!),是否有一种方法可以通过编程方式强制其中一个线程前进到它可能卡住的WaitForSingleObject,从而解决死锁?我不一定要终止线程,我只是想让它继续前进(从而允许线程“优雅地”退出)。(是的,我知道这听起来像是我之前的问题Delphi2006-What'sthebestwaytogracefullykillathreadandstillhavetheOnTerminatehandlerfire?的重复,但情况略有不同-我在这里问的是是否有可能制作WaitF

windows - pthreads 和 CreateThread 的死锁

我在Windows应用程序中使用pthreads。我注意到我的程序陷入了僵局——快速检查表明发生了以下情况:线程1生成了线程2。线程2生成了线程3。线程2等待来自线程3的互斥量,而线程3没有解锁。所以,我去gdb中调试,在回溯第三个线程时得到以下信息:Thread3(thread3456.0x880):#00x7c8106e9inKERNEL32!CreateThread()from/cygdrive/c/WINDOWS/system32/kernel32.dllCannotaccessmemoryataddress0x131不知何故,它在WindowsCreateThread函数中卡

c++ - 在卸载 DLL 期间删除静态对象时退出线程会导致死锁?

我的延迟加载DLL中有一个实例(全局/静态对象)ClassA。这个对象里面有一个“观察者”线程,它需要执行正常关闭。当我调用FreeLibrary时,我注意到在删除此静态对象期间,我的线程请求关闭但卡在_endthreadex()上并导致死锁。显式或隐式调用_endthreadex都没有关系。对象是全局的还是静态的并不重要——结果相同。此线程包装在ClassB中(通过带有自定义消息循环的模板实现)。有一个关闭线程(发布消息)的请求并跟随WaitForSingleObject,它永远不会为给定的线程句柄返回。代码中到处都使用相同的“模板线程类”,关闭效果很好。删除静态对象时的唯一问题。我

c++ - 什么会导致单写/多读锁的死锁?

我有一个类实例,其他线程中的其他几个类使用该类实例进行通信。这个类使用一个slimreader/writer锁(WinAPI的SRWLOCK)作为一个同步对象和几个RAII辅助类来实际锁定/解锁这个东西:staticunsignedintreadCounter=0;classCReadLock{public:CReadLock(SRWLOCK&Lock):m_Lock(Lock){InterlockedIncrement(&readCounter);AcquireSRWLockShared(&m_Lock);}~CReadLock(){ReleaseSRWLockShared(m_Lo