C++ 死锁及解决办法
https://blog.csdn.net/weixin_38416696/article/details/90598963
一,忘记释放锁
mutex _mutex; void func() { _mutex.lock(); if (xxx) return; _mutex.unlock(); }
二,单线程重复申请锁
mutex _mutex; void func() { _mutex.lock(); //do somrthing.... _mutex.unlock(); } void data_process() { _mutex.lock(); func(); _mutex.unlock(); }
三,双线程多锁申请
mutex _mutex1; mutex _mutex2; void process1() { _mutex1.lock(); _mutex2.lock(); //do something1... _mutex2.unlock(); _mutex1.unlock(); } void process2() { _mutex2.lock(); _mutex1.lock(); //do something2... _mutex1.unlock(); _mutex2.unlock(); }
https://blog.csdn.net/u010275850/article/details/100108969
C++ 11 中的几种锁
标准C++库提供了std::unique_lock类模板,实现了互斥锁的RAII惯用语法:
std::unique_lock<std::mutex> lk(mtx_sync_);
条件锁(condition_variable)
条件锁就是所谓的条件变量,某一个线程因为某个条件未满足时可以使用条件变量使该程序处于阻塞状态。一旦条件满足了,即可唤醒该线程(常和互斥锁配合使用),唤醒后,需要检查变量,避免虚假唤醒。
线程1: // wait ack { std::unique_lock<std::mutex> lk(mtx_sync_); if (!cv_sync_.wait_for(lk, 1000ms, [this](){return sync_; })) // wait for 1s { // wait failed printf("wait for notify timeout [%d].\n", cnt); return false; } else { return true; } } 线程2: { std::unique_lock<std::mutex> lk(mtx_sync_); sync_ = true; } // 通知前解锁,可以避免唤醒线程后由于互斥锁的关系又进入了阻塞阶段 cv_sync_.notify_one();
自旋锁(不推荐使用)
递归锁(recursive_mutex)
recursive_mutex 类是同步原语,能用于保护共享数据免受从个多线程同时访问。
recursive_mutex 提供排他性递归所有权语义:
调用方线程在从它成功调用 lock 或 try_lock 开始的时期里占有 recursive_mutex 。此时期间,线程可以进行对 lock 或 try_lock 的附加调用。所有权的时期在线程调用 unlock 匹配次数时结束。
线程占有 recursive_mutex 时,若其他所有线程试图要求 recursive_mutex 的所有权,则它们将阻塞(对于调用 lock )或收到 false 返回值(对于调用 try_lock )。
可锁定 recursive_mutex 次数的最大值是未指定的,但抵达该数后,对 lock 的调用将抛出 std::system_error 而对 try_lock 的调用将返回 false 。
若 recursive_mutex 在仍为某线程占有时被销毁,则程序行为未定义。 recursive_mutex 类满足互斥 (Mutex) 和标准布局类型 (StandardLayoutType) 的所有要求。