C++ mutex lock_guard unique_lock使用说明

1. std::mutex

类似函数std::recursive_mutex 允许同一个线程多次获取同一个互斥量

头文件#include <mutex>

mutex::lock(),给共享内存加锁

...

...  //待保护代码或者共享内存等等

...

mutex::unlock(),给共享内存解锁

比如:

std::mutex m;

m.lock();

...

m.unlock();

 

2. std::lock_guard<std::mutex> (模板类)

头文件#include <mutex>

比如:

1)

std::mutex m;

{

std::lock_gurad<std::mutex> lguard(m); //类中默认加锁作用域,作用域执行完毕类析构中自动解锁

... //作用域在大括号中,作用域结束,lguard自动unlock。

}

2)

std::mutex m;

{

m.lock();

std::lock_guard<std::mutex> lguard(m, std::adopt_lock); //使用adopt_lock选项默认为未加锁,但是执行完作用域类析构函数中自动解锁。

...  //作用域在大括号内,作用域结束,lguard自动unlock。

}

3)

std::mutex m;

{

std::lock_guard<std::mutex> lguard(m); //默认已经加锁

std::mutex *pmtx = lguard.release(); //解除lguard和m之间的关联关系,此时m已经加锁,并未解锁,所以后面需要解锁

...  //作用域在大括号内,作用域结束,lguard自动unlock。

pmtx->unlock();

}

 

3. std::unique_lock<std::mutex>

头文件#include <mutex>

  1. 拥有方法std::unique_lock<std::mutex>::owns_lock(),判断当前是否锁定该锁。
  2. 拥有方法std::unique_lock<std::mutex>::try_lock(),尝试加锁,如果返回true则加锁成功,否则加锁失败,不阻塞。
  3. 拥有方法std::unique_lock<std::mutex>::release(),返回它管理的mutex对象指针,并释放所有权;也就是说,这个unique_lock和mutex不在有关系。

比如:

1)

std::mutex m;

{

std::unique_lock<std::mutex> uguard(m); //类中默认加锁作用域,作用域执行完毕类析构中自动解锁

... //作用域在大括号中,作用域结束,uguard自动unlock。

}

2)

std::mutex m;

{

m.lock();

std::unique_lock<std::mutex> uguard(m, std::adopt_lock); //使用adopt_lock选项默认为未加锁,但是执行完作用域类析构函数中自动解锁。

...  //作用域在大括号内,作用域结束,uguard自动unlock。

}

3)

std::mutex m;

{

std::unique_lock<std::mutex> uguard(m, std::try_to_lock); //解决一个线程加锁后占用事件较长,另一个线程等待较长时间的问题

...  //作用域在大括号内,作用域结束,uguard自动unlock。

}

4)

std::mutex m;

{

std::unique_lock<std::mutex> uguard(m, std::defer_lock); //1. 解决线程临时需要释放锁,之后再次加锁的情况。2. 如果后面不使用lock和unlock功能和示例3一样。

uguard.lock(); //加锁

...  //作用域在大括号内,作用域结束,uguard自动unlock。

 

另外也可以手动lock和unlock。

uguard.unlock();

...

...

uguard.lock();

...

...

uguard.unlock();

}

5)

std::mutex m;

{

std::unique_lock<std::mutex> uguard(m, std::defer_lock); //1. 解决线程临时需要释放锁,之后再次加锁的情况。2. 如果后面不使用lock和unlock功能和示例3一样。

uguard.lock(); //加锁

...  //作用域在大括号内,作用域结束,uguard自动unlock。

 

if( uguard.owns_lock() == true){

... //加锁成功,执行共享内存代码

}

else{

... //加锁没有成功

}

}

6)

std::mutex m;

{

std::unique_lock<std::mutex> uguard(m, std::defer_lock); //1. 解决线程临时需要释放锁,之后再次加锁的情况。2. 如果后面不使用lock和unlock功能和示例3一样。

 

...  //作用域在大括号内,作用域结束,uguard自动unlock。

 

if(uguard.try_lock() == true){

... //加锁成功,执行共享内存代码

}

else{

... //加锁没有成功

}

}

7)

std::mutex m;

{

std::unique_lock<std::mutex> uguard(m); //默认已经加锁

std::mutex *pmtx = uguard.release(); //解除uguard和m之间的关联关系,此时m已经加锁,并未解锁,所以后面需要解锁

...  //作用域在大括号内,作用域结束,uguard自动unlock。

pmtx->unlock();

}

 

4. std::lock()函数

功能:一次加多把锁,避免死锁

头文件:#include <mutex>

比如:

1)

std::mutex m1, m2;

std::lock(m1, m2) //m1,m2同时上锁

... //访问共享变量

m1.unlock();

m2.unlock();

2)

std::mutex m1, m2;

std::lock(m1, m2) //m1,m2同时上锁

std::lock_guard<std::mutex> lguard1(m1, std::adopt_lock); //用lock_guard自动unlock锁

std::lock_guard<std::mutex> lguard2(m2, std::adopt_lock);

... //访问共享变量

//不再需要unlock锁m1和m2了

3)

std::mutex m1, m2;

std::lock(m1, m2) //m1,m2同时上锁

std::unique_guard<std::mutex> uguard1(m1, std::adopt_lock); //用lock_guard自动unlock锁

std::unique_guard<std::mutex> uguard2(m2, std::adopt_lock);

... //访问共享变量

//不再需要unlock锁m1和m2了

 

5. std::timed_mutex 带超时功能的独占互斥量

类似函数std::recursive_timed_mutex 允许同一个线程多次获取同一个互斥量

头文件#include <mutex>

  1. try_lock_for()函数:等待一段时间。如果拿到锁或者等待超时,就往下执行。
  2. try_lock_until()函数:参数是一个未来时间点,在未来一段时间内如果拿到锁就走下来;如果时间到了没有拿到锁,程序也走下来。

比如:

1)

std::timed_mutex m;

std::chrono::millisecond timeout(100);

if(m.try_lock_for(timeout)){ //程序等待100毫秒尝试拿锁,如果拿到锁执行if,否则else

... //拿到锁,执行互斥内容

m.unlock();

}

else{

... //没有拿到锁

}

2)

std::timed_mutex m;

std::chrono::millisecond timeout(100);

if(m.try_lock_until(std::chrono::steady_clock::now() + timeout)){ //程序从当前时间开始经过100毫秒时间,如果拿到锁,执行if,否则执行else

... //执行互斥内容

m.unlock();

}

else{

... //没有拿到锁

}

以上内容,详情查看文档

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值