首页 > C++ 多线程:互斥对象 lock_gurad

C++ 多线程:互斥对象 lock_gurad

描述

  • 头文件:
  • 声明方式: template< class Mutex > class lock_guard;
  • 简介

    lock_guard是一种互斥包装器,它提供了非常便捷的raii资源管控技术用来在对象生存周期内提供互斥锁。

    lock_gurad很好得解决了互斥变量mutex的锁成员在函数异常期间无法正常回收资源的问题。当lock_guard对象创建之时即尝试获取锁的所有权,当该对象离开其所创建的作用域时会销毁lock_gurad并释放互斥变量的锁。

    PS:lock_guard 对象是不可赋值的,它不支持赋值运算符

成员函数

  • 构造函数std::lock_guard::lock_guard

    • explicit lock_guard( mutex_type& m ); (1)
    • lock_guard( mutex_type& m, std::adopt_lock_t t ); (2)
    • lock_guard( const lock_guard& ) = delete; (3)

    获得给定的互斥变量所有权:

    (1) 等效于调用m.lock()成员。若m不是递归锁(即传入地址),且当前线程已经占有m,则当前构造是未定义的

    (2)获得互斥m的所有权但并不调用lock进行锁定,若当前线程不占有m,则构造是未定义的。

    (3)不存在拷贝构造函数

    如果m先于lock_guard被销毁,则构造函数未定义

  • 析构函数std::lock_guard::~lock_guard

    释放所占有互斥的所有权。

    等效地调用 m.unlock() ,其中 m 是传递个 lock_guard 的构造函数的互斥。

使用案例如下:

#include 
#include 
#include int g_i = 0;
std::mutex g_i_mutex;  // protects g_ivoid safe_increment()
{ std::lock_guard<std::mutex> lock(g_i_mutex);for (int i = 0;i < 10; ++i){ ++g_i;std::cout << std::this_thread::get_id() << ": " << g_i << '
';}// 当lock_guard离开当前作用域时mutex互斥量会自动释放
}int main()
{ std::cout << "main: " << g_i << '
';std::thread t1(safe_increment);std::thread t2(safe_increment);t1.join();t2.join();std::cout << "main: " << g_i << '
';
}

输出如下:

main: 0
0x700004de4000: 1
0x700004de4000: 2
0x700004de4000: 3
0x700004de4000: 4
0x700004de4000: 5
0x700004de4000: 6
0x700004de4000: 7
0x700004de4000: 8
0x700004de4000: 9
0x700004de4000: 10
0x700004e67000: 11
0x700004e67000: 12
0x700004e67000: 13
0x700004e67000: 14
0x700004e67000: 15
0x700004e67000: 16
0x700004e67000: 17
0x700004e67000: 18
0x700004e67000: 19
0x700004e67000: 20
main: 20

总结

lock_guard提供了自动回收资源的raii技术,能够在对象构造时加锁,析构时解锁,防止因程序异常退出或者忘记unlock造成的死锁问题

更多相关:

  • apt Could not get lock /var/lib/dpkg/lock 解决方案 删除锁定文件 sudo rm /var/lib/dpkg/lock...

  • 经过长期探索,发现一个不需要手动设置线程休眠时间(e.g. std::this_thread::sleep_for(std::chrono::microseconds(1)))的代码: Github: https://github.com/log4cplus/ThreadPool #ifndef THREAD_POOL_H_7e...

  • nth_element(first,nth,last) first,last 第一个和最后一个迭代器,也可以直接用数组的位置。  nth,要定位的第nn 个元素,能对它进行随机访问. 将第n_thn_th 元素放到它该放的位置上,左边元素都小于它,右边元素都大于它. 测试代码: http://www.cplusplus.com...

  • c/c++老版本的rand()存在一定的问题,在转换rand随机数的范围,类型或者分布时,常常会引入非随机性。 定义在 中的随机数库通过一组协作类来解决这类问题:随机数引擎 和 随机数分布类 一个给定的随机数发生器一直会生成相同的随机数序列。一个函数如果定义了局部的随机数发生器,应该将(引擎和分布对象)定义为 st...

  • jsoncpp 是一个C++ 语言实现的json库,非常方便得支持C++得各种数据类型到json 以及 json到各种数据类型的转化。 一个json 类型的数据如下: {"code" : 10.01,"files" : "","msg" : "","uploadid" : "UP000000" } 这种数据类型方便我们人阅读以...

  • 问题如下: 已知一组数(其中有重复元素),求这组数可以组成的所有子集中,子 集中的各个元素和为整数target的子集,结果中无重复的子集。 例如: nums[] = [10, 1, 2, 7, 6, 1, 5], target = 8 结果为: [[1, 7], [1, 2, 5], [2, 6], [1, 1, 6]] 同样之前有...