3.1 手动实现RAii管理mutex资源锁自动释放
自己写的代码一般都是自己上锁,自己进行释放,但是这样特别容易忘记释放,进而造成死锁(可以理解为一直没有被释放的锁),为了确保每一个锁都能得到释放,所以就有了这样一个技术,叫做RAii资源获取既初始化,特性就是使用局部对象来管理资源,局部对象我们都知道,他一旦出栈就会得到释放,在一对大括号之中的代码,里面生成的变量和对象,一旦出了这对大括号,他就会得到释放,若是类的对象的话,他会调用析构函数进行释放,这部分代码我们称为是在栈中生成的空间,所以他们的运行周期由操作系统来维护。
使用局部对象来管理资源的技术称为资源获取即初始化;它的生命周期是由操作系统来管理的,无需人工介入;资源的销毁容易忘记,造成死锁或内存泄漏。
#include <thread>
#include <iostream>
#include <string>
#include <mutex>
#include <shared_mutex>
//Linux -lpthread
using namespace std;
// RAII 这个是把上锁和解锁的过程放在类当中
class XMutex
{
public:
XMutex(mutex& mux) :mux_(mux)
{
cout << "Lock" << endl;
mux.lock();
}
~XMutex()
{
cout << "Unlock" << endl;
mux_.unlock();
}
private:
mutex& mux_;
};
static mutex mux;
void TestMutex(int status)
{
XMutex lock(mux);
if (status == 1)
{
cout << "=1" << endl;
return;
}
else
{
cout << "!=1" << endl;
return;
}
}
int main(int argc, char* argv[])
{
TestMutex(1);
TestMutex(2);
getchar();
return 0;
}
类名后面跟着一个lock(mux),lock其实是一个对象,并且给有参构造函数传递了一个实参。
3.2 c++11自带的RAIl控制锁lock guard
#include <thread>
#include <iostream>
#include <string>
#include <mutex>
#include <shared_mutex>
//Linux -lpthread
using namespace std;
static mutex gmutex; //这里可以是任意的互斥变量类型,只要里面包含lock函数的都可以
void TestLockGuard(int i)
{
gmutex.lock();
{
//假如外部已经有锁,那就不lock
lock_guard<mutex> lock(gmutex, adopt_lock);
//出了大括号,调用析构函数,释放锁
}
{
lock_guard<mutex> lock(gmutex);
cout << "begin thread " << i << endl;
}
for (;;)
{
{
lock_guard<mutex> lock(gmutex);
cout << "In " << i << endl;
}
this_thread::sleep_for(500ms);
}
}
int main(int argc, char* argv[])
{
for (int i = 0; i < 3; i++)
{
thread th(TestLockGuard, i + 1);
th.detach();
}
getchar();
retu