1 死锁:每个线程都希望锁住一些列锁以执行某个操作,且每个线程持有一个不同的锁,最终每个线程都需要其它线程的锁,导致所有线程都不能向前执行。
1.1 顺序加锁lock
1.1 死锁的一个解决方式:每个线程对锁的请求顺序一致。C++库提供了顺序加锁机制,可以一次性锁住多个mutex而不会出现死锁:
void lock (Mutex1& a, Mutex2& b, Mutexes&... cde);
对a,b...cde锁顺序加锁,若在加锁过程中抛出任何异常就释放前面已持有的锁。不会出现死锁,一个例子如下:
#include <mutex>
#include<unistd.h>
#include<thread>
#include<iostream>
using namespace std;
class big_object
{
public:
big_object(int i=0):data(i){}
public:
int data;
};
void swap(big_object& lhs,big_object& rhs)
{
sleep(1);
cout<<"swap()"<<endl;
}
class X
{
private:
big_object some_detail;
mutable std::mutex m;
public:
X(big_object const& sd):some_detail(sd){}
friend void swap(X& lhs, X& rhs)
{
if(&lhs==&rhs)
return;
std::lock(lhs.m,rhs.m);//C++库会自动生成加锁顺序,即使调用顺序不一致
std::lock_guard<std::mutex> lock_a(lhs.m,std::adopt_lock);//adopt_lock是告诉lock_guard对象mutex已经被上锁,而lock_gurad对象将获得mutex的所有权,这样就可以保证在lock可能出现异常导致没有unlock的情形不会出现,栈对象会在异常抛出后自动析构
std::lock_guard<std::mutex> lock_b(rhs.m,