当前位置: 首页 > 编程日记 > 正文

C++11中std::unique_lock的使用

std::unique_lock为锁管理模板类,是对通用mutex的封装。std::unique_lock对象以独占所有权的方式(unique owership)管理mutex对象的上锁和解锁操作,即在unique_lock对象的声明周期内,它所管理的锁对象会一直保持上锁状态;而unique_lock的生命周期结束之后,它所管理的锁对象会被解锁。unique_lock具有lock_guard的所有功能,而且更为灵活。虽然二者的对象都不能复制,但是unique_lock可以移动(movable),因此用unique_lock管理互斥对象,可以作为函数的返回值,也可以放到STL的容器中。

关于std::mutex的基础介绍可以参考:http://blog.csdn.net/fengbingchun/article/details/73521630

std::unique_lock还支持同时锁定多个mutex,这避免了多道加锁时的资源”死锁”问题。在使用std::condition_variable时需要使用std::unique_lock而不应该使用std::lock_guard。

std::unique_lock类成员函数介绍:

(1). unique_lock构造函数:禁止拷贝构造,允许移动构造;

(2). operator =:赋值操作符,允许移动赋值,禁止拷贝赋值;

(3). operator bool:返回当前std::unique_lock对象是否获得了锁;

(4). lock函数:调用所管理的mutex对象的lock函数;

(5). try_lock函数:调用所管理的mutex对象的try_lock函数;

(6).try_lock_for函数:调用所管理的mutex对象的try_lock_for函数;

(7).try_lock_until函数:调用所管理的mutex对象的try_lock_until函数;

(8). unlock函数:调用所管理的mutex对象的unlock函数;

(9). release函数:返回所管理的mutex对象的指针,并释放所有权,但不改变mutex对象的状态;

(10). owns_lock函数:返回当前std::unique_lock对象是否获得了锁;

(11). mutex函数:返回当前std::unique_lock对象所管理的mutex对象的指针;

(12). swap函数:交换两个unique_lock对象。

The difference is that you can lock and unlock a std::unique_lock. std::lock_guard will be locked only once on construction and unlocked on destruction.

std::unique_lock has other features that allow it to e.g.: be constructed without locking the mutex immediately but to build the RAII wrapper. However, std::unique_lock might have a tad more overhead(较多开销).

std::lock_guard also provides a convenient RAII wrapper, but cannot lock multiple mutexes safely. It can be used when you need a wrapper for a limited scope, e.g.: a member function.

One of the differences between std::lock_guard and std::unique_lock is that the programmer is able to unlock std::unique_lock, but she/he is not able to unlock std::lock_guard.

下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:

#include "unique_lock.hpp"
#include <iostream>
#include <thread>
#include <mutex>
#include <vector>
#include <chrono>namespace unique_lock_ {//
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/unique_lock/
namespace {
std::mutex foo, bar;void task_a()
{std::lock(foo, bar);         // simultaneous lock (prevents deadlock)std::unique_lock<std::mutex> lck1(foo, std::adopt_lock);std::unique_lock<std::mutex> lck2(bar, std::adopt_lock);std::cout << "task a\n";// (unlocked automatically on destruction of lck1 and lck2)
}void task_b()
{// unique_lock::unique_lock: Constructs a unique_lock// foo.lock(); bar.lock(); // replaced by:std::unique_lock<std::mutex> lck1, lck2;lck1 = std::unique_lock<std::mutex>(bar, std::defer_lock);lck2 = std::unique_lock<std::mutex>(foo, std::defer_lock);std::lock(lck1, lck2);       // simultaneous lock (prevents deadlock)std::cout << "task b\n";// (unlocked automatically on destruction of lck1 and lck2)
}
}int test_unique_lock_1()
{std::thread th1(task_a);std::thread th2(task_b);th1.join();th2.join();return 0;
}/
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/lock/
namespace {
std::mutex mtx;           // mutex for critical sectionvoid print_thread_id(int id) {std::unique_lock<std::mutex> lck(mtx, std::defer_lock);// critical section (exclusive access to std::cout signaled by locking lck):// unique_lock::lock: Calls member lock of the managed mutex object.lck.lock();std::cout << "thread #" << id << '\n';// unique_lock::unlock: Calls member unlock of the managed mutex object, and sets the owning state to falselck.unlock();
}
}int test_unique_lock_2()
{std::thread threads[10];// spawn 10 threads:for (int i = 0; i<10; ++i)threads[i] = std::thread(print_thread_id, i + 1);for (auto& th : threads) th.join();return 0;
}//
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/mutex/
namespace {
class MyMutex : public std::mutex {int _id;
public:MyMutex(int id) : _id(id) {}int id() { return _id; }
};MyMutex mtx3(101);void print_ids(int id) {std::unique_lock<MyMutex> lck(mtx3);// unique_lock::mutex: Returns a pointer to the managed mutex objectstd::cout << "thread #" << id << " locked mutex " << lck.mutex()->id() << '\n';
}
}int test_unique_lock_3()
{std::thread threads[10];// spawn 10 threads:for (int i = 0; i<10; ++i)threads[i] = std::thread(print_ids, i + 1);for (auto& th : threads) th.join();return 0;
}//
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/operator=/
namespace {
std::mutex mtx4;           // mutex for critical sectionvoid print_fifty(char c) {std::unique_lock<std::mutex> lck;         // default-constructed// unique_lock::operator=: Replaces the managed mutex object by the one in x, including its owning statelck = std::unique_lock<std::mutex>(mtx4);  // move-assignedfor (int i = 0; i<50; ++i) { std::cout << c; }std::cout << '\n';
}
}int test_unique_lock_4()
{std::thread th1(print_fifty, '*');std::thread th2(print_fifty, '$');th1.join();th2.join();return 0;
}///
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/operator_bool/
namespace {
std::mutex mtx5;           // mutex for critical sectionvoid print_star() {std::unique_lock<std::mutex> lck(mtx5, std::try_to_lock);// print '*' if successfully locked, 'x' otherwise:// unique_lock::operator bool: Return whether it owns a lockif (lck)std::cout << '*';elsestd::cout << 'x';
}
}int test_unique_lock_5()
{std::vector<std::thread> threads;for (int i = 0; i<500; ++i)threads.emplace_back(print_star);for (auto& x : threads) x.join();return 0;
}///
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/owns_lock/
namespace {
std::mutex mtx6;           // mutex for critical sectionvoid print_star6() {std::unique_lock<std::mutex> lck(mtx6, std::try_to_lock);// print '*' if successfully locked, 'x' otherwise:// unique_lock::owns_lock: Returns whether the object owns a lock.if (lck.owns_lock())std::cout << '*';elsestd::cout << 'x';
}
}int test_unique_lock_6()
{std::vector<std::thread> threads;for (int i = 0; i<500; ++i)threads.emplace_back(print_star6);for (auto& x : threads) x.join();return 0;
}//
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/release/
namespace {
std::mutex mtx7;
int count = 0;void print_count_and_unlock(std::mutex* p_mtx) {std::cout << "count: " << count << '\n';p_mtx->unlock();
}void task() {std::unique_lock<std::mutex> lck(mtx7);++count;// unique_lock::release: Returns a pointer to the managed mutex object, releasing ownership over itprint_count_and_unlock(lck.release());
}
}int test_unique_lock_7()
{std::vector<std::thread> threads;for (int i = 0; i<10; ++i)threads.emplace_back(task);for (auto& x : threads) x.join();return 0;
}/
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/try_lock/
namespace {
std::mutex mtx8;           // mutex for critical sectionvoid print_star8() {std::unique_lock<std::mutex> lck(mtx8, std::defer_lock);// print '*' if successfully locked, 'x' otherwise:// unique_lock::try_lock: Lock mutex if not locked// true if the function succeeds in locking the managed mutex object, false otherwise.if (lck.try_lock())std::cout << '*';elsestd::cout << 'x';
}
}int test_unique_lock_8()
{std::vector<std::thread> threads;for (int i = 0; i<500; ++i)threads.emplace_back(print_star8);for (auto& x : threads) x.join();return 0;
}/
// reference: http://www.cplusplus.com/reference/mutex/unique_lock/try_lock_for/
namespace {
std::timed_mutex mtx9;void fireworks() {std::unique_lock<std::timed_mutex> lck(mtx9, std::defer_lock);// waiting to get a lock: each thread prints "-" every 200ms:// unique_lock::try_lock_for: Try to lock mutex during time spanwhile (!lck.try_lock_for(std::chrono::milliseconds(200))) {std::cout << "-";}// got a lock! - wait for 1s, then this thread prints "*"std::this_thread::sleep_for(std::chrono::milliseconds(1000));std::cout << "*\n";
}
}int test_unique_lock_9()
{std::thread threads[10];// spawn 10 threads:for (int i = 0; i<10; ++i)threads[i] = std::thread(fireworks);for (auto& th : threads) th.join();return 0;
}/
// reference: http://en.cppreference.com/w/cpp/thread/unique_lock
namespace {
struct Box {explicit Box(int num) : num_things{ num } {}int num_things;std::mutex m;
};void transfer(Box& from, Box& to, int num)
{// don't actually take the locks yetstd::unique_lock<std::mutex> lock1(from.m, std::defer_lock);std::unique_lock<std::mutex> lock2(to.m, std::defer_lock);// lock both unique_locks without deadlockstd::lock(lock1, lock2);from.num_things -= num;to.num_things += num;// 'from.m' and 'to.m' mutexes unlocked in 'unique_lock' dtors
}
}int test_unique_lock_10()
{Box acc1(100);Box acc2(50);std::thread t1(transfer, std::ref(acc1), std::ref(acc2), 10);std::thread t2(transfer, std::ref(acc2), std::ref(acc1), 5);t1.join();t2.join();return 0;
}} // namespace unique_lock_

GitHub: https://github.com/fengbingchun/Messy_Test

相关文章:

为何Google将几十亿行源代码放在一个仓库?| CSDN博文精选

作者 | Rachel Potvin&#xff0c;Josh Levenberg译者 | 张建军编辑 | apddd【AI科技大本营导读】与大多数开发者的想象不同&#xff0c;Google只有一个代码仓库——全公司使用不同语言编写的超过10亿文件&#xff0c;近百TB源代码都存放在自行开发的版本管理系统Piper中&#…

小小hanoi

为什么80%的码农都做不了架构师&#xff1f;>>> View Code #include " iostream " using namespace std; int k 0 ; void hanoi( int m , char a , char b, char c){ if (m 1 ) { k ; printf( " %c->%c " ,a , c); return…

Unity3D心得分享

本篇文章的内容以各种tips为主&#xff0c;不间断更新 2019/05/10 最近更新&#xff1a; 使用Instantiate初始化参数去实例对象 Unity DEMO学习 Unity3D Adam Demo的学习与研究 Unity3D The Blacksmith Demo部分内容学习 Viking Village维京村落demo中的地面积水效果 Viking V…

django搭建示例-ubantu环境

python3安装--------------------------------------------------------------------------- 最新的django依赖python3,同时ubantu系统默认自带python2与python3&#xff0c;这里单独安装一套python3&#xff0c;并且不影响原来的python环境 django demo使用sqlite3&#xff0c…

C++11中std::lock_guard的使用

互斥类的最重要成员函数是lock()和unlock()。在进入临界区时&#xff0c;执行lock()加锁操作&#xff0c;如果这时已经被其它线程锁住&#xff0c;则当前线程在此排队等待。退出临界区时&#xff0c;执行unlock()解锁操作。更好的办法是采用”资源分配时初始化”(RAII)方法来加…

OpenAI机械手单手轻松解魔方,背靠强化学习+新技术ADR

编译 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】10月15日&#xff0c;人工智能研究机构OpenAI发布了一条机械手单手解魔方的视频。这个自学式的类人机器人手臂名为 Dactyl&#xff0c;不仅可以单手解魔方&#xff0c;甚至能在外加各种干扰&#x…

AMD and CMD are dead之js模块化黑魔法

缘由 在2013-03-06 13:58的时候&#xff0c;曾甩下一片文章叫&#xff1a;《为什么不使用requirejs和seajs》&#xff0c;并放下豪言说发布一款完美的模块化库&#xff0c;再后来就把那篇文章删了&#xff0c;再然后就没有然后。该用seajs还用seajs&#xff0c;甚至我码的SCJ都…

一文了解Python常见的序列化操作

关于我 编程界的一名小小程序猿&#xff0c;目前在一个创业团队任team lead&#xff0c;技术栈涉及Android、Python、Java和Go&#xff0c;这个也是我们团队的主要技术栈。 联系&#xff1a;hylinux1024gmail.com 0x00 marshal marshal使用的是与Python语言相关但与机器无关的二…

TEE(Trusted Execution Environment)简介

TEE(Trusted Execution Environment)&#xff0c;可信执行环境&#xff0c;该环境可以保证不被常规操作系统干扰的计算&#xff0c;因此称为”可信”。这是通过创建一个可以在TrustZone的”安全世界”中独立运行的小型操作系统实现的&#xff0c;该操作系统以系统调用(由TrustZ…

自动驾驶关键环节:行人的行为意图建模和预测(上)

作者 | 黄浴出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;【导读】介绍一下最近行人行为意图建模和预测的研究工作&#xff0c;还是分上下两部分&#xff0c;本文为上半部分。Social LSTM: Human Trajectory Prediction in Crowded Spaces比较早的是斯坦福大学 201…

自定义windows下自动清除文件夹或者文件的只读属性的脚本

脚本内容入下&#xff1a;其中脚本中 ”/d"作用 &#xff08;可以用来改变当前驱动器目录&#xff09;例如&#xff1a; 我现在是在D盘&#xff0c;现在我要切换到C:\windows目录 脚本参数中 ATTRIB -R /S /D 解释内容如下&#xff1a;&#xff08;上述脚本参数中的 cd …

C++11容器中新增加的emplace相关函数的使用

C11中&#xff0c;针对顺序容器(如vector、deque、list)&#xff0c;新标准引入了三个新成员&#xff1a;emplace_front、emplace和emplace_back&#xff0c;这些操作构造而不是拷贝元素。这些操作分别对应push_front、insert和push_back&#xff0c;允许我们将元素放置在容器头…

Silverlight+WCF 新手实例 象棋 主界面-棋谱-获取列表(三十八)

2019独角兽企业重金招聘Python工程师标准>>> 在线演示地址&#xff1a;SilverlightWCF 新手实例 象棋 在线演示 在SilverlightWCF 新手实例 象棋 主界面-棋谱-布局写谱(三十六)中&#xff0c;我们完成下棋双方的棋谱显示&#xff0c;这节&#xff0c;我们为观众增加…

确认!语音识别大牛Daniel Povey将入职小米,曾遭霍普金斯大学解雇,怒拒Facebook

整理 | 夕颜 出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09; 【导读】10 月 17 日&#xff0c;语音界传奇 Daniel Povey 发布推特&#xff0c;宣布自己 2019 年末将要入职小米&#xff0c;目前正在签订合同阶段&#xff0c;入职后&#xff0c;他将带领一支团队研发…

软链接与硬链接

$ ln f1 f2 #创建f1的一个硬连接文件f2$ ln -s f1 f3 #创建f1的一个符号连接文件f3$ ls -li # -i参数显示文件的inode节点信息转载于:https://www.cnblogs.com/zhizouxiao/p/3794668.html

一文读懂Python复杂网络分析库networkx | CSDN博文精选

作者 | yyl424525来源 | CSDN博客文章目录1. 简介安装支持四种图绘制网络图基本流程2. Graph-无向图节点边属性有向图和无向图互转3. DiGraph-有向图一些精美的图例子环形树状图权重图Giant ComponentRandom Geometric Graph 随机几何图节点颜色渐变边的颜色渐变Atlas画个五角星…

C++11多线程中std::call_once的使用

C11中的std::call_once函数位于<mutex>头文件中。在多线程编程中&#xff0c;有时某个任务只需要执行一次&#xff0c;此时可以用C11中的std::call_once函数配合std::once_flag来实现。如果多个线程需要同时调用某个函数&#xff0c;std::call_once可以保证多个线程对该函…

Solaris 上网配置

2019独角兽企业重金招聘Python工程师标准>>> 早上装solaris10系统的时候&#xff0c;没选默认&#xff0c;选了desk-session模式安装。全英文无界面安装&#xff0c;中间还跑出几个乱码。 靠着随便选随便F2&#xff0c;终于安装完了。 就在那设完分辨率后&#xff0…

Configure,Makefile.am, Makefile.in, Makefile文件之间关系

为什么80%的码农都做不了架构师&#xff1f;>>> 1.autoscan (autoconf): 扫描源代码以搜寻普通的可移植性问题&#xff0c;比如检查编译器&#xff0c;库&#xff0c;头文件等&#xff0c;生成文件configure.scan,它是configure.ac的一个雏形。 your source files…

这款耳机一点不输千元级的AirPods

你如果问我&#xff1a;生活中你觉得必不可少的一件电子产品是什么&#xff1f;那么我会毫不犹豫的回答你&#xff1a;是耳机&#xff01;出门忘带耳机是绝对不能忍听不听没关系&#xff0c;但是有它比较安心我觉得生活中不仅是我很多人都对耳机有一种依赖因为很多人都喜欢音乐…

CUDA Samples: Image Process: BGR to Gray

在图像处理中&#xff0c;颜色变换BGR到Gray&#xff0c;常见的一般有两种计算方式&#xff0c;一种是基于浮点数计算&#xff0c;一种是基于性能优化的通过移位的整数计算。浮点数计算公式为&#xff1a; gray 0.1140 * B 0.5870 * G 0.2989 * R;整数计算公式为&#xff1…

CYQ.Data 数据框架系列索引

2019独角兽企业重金招聘Python工程师标准>>> 索引基础导航&#xff1a; 1&#xff1a;下载地址&#xff1a;http://www.cyqdata.com/download/article-detail-426 2&#xff1a;入门教程&#xff1a;http://www.cyqdata.com/cyqdata/article-cate-33 3&#xff1a;购…

Tesseract 3 语言数据的训练方法

OCR,光学字符识别 光学字符识别(OCR,Optical Character Recognition)是指对文本资料进行扫描&#xff0c;然后对图像文件进行分析处理&#xff0c;获取文字及版面信息的过程。OCR技术非常专业&#xff0c;一般多是印刷、打印行业的从业人员使用&#xff0c;可以快速的将纸质资料…

Windows C++中__declspec(dllexport)的使用

__declspec是Microsoft VC中专用的关键字&#xff0c;它配合着一些属性可以对标准C/C进行扩充。__declspec关键字应该出现在声明的前面。 __declspec(dllexport)用于Windows中的动态库中&#xff0c;声明导出函数、类、对象等供外面调用&#xff0c;省略给出.def文件。即将函数…

图灵奖得主LeCun力推无监督学习:要重视基于能量的学习方法

作者 | Tiernan Ray译者 | 夕颜出品 | AI科技大本营&#xff08;ID:rgznai100&#xff09;导语&#xff1a;图灵奖得主深度学习大牛 Yann LeCun 表示&#xff0c;人工智能的下一个发展方向可能是放弃深度学习的所有概率技巧&#xff0c;转而掌握一系列转移能量值的方法。据说&a…

html5小游戏Untangle

2019独角兽企业重金招聘Python工程师标准>>> 今天介绍一个HTML5的小游戏&#xff0c;让大家体验到HTML5带来的乐趣。这个小游戏很简单&#xff0c;只要用鼠标拖动 蓝点&#xff0c;让图上的所有线都不相交&#xff0c;游戏时间就会停止&#xff0c;是动用大家头脑的…

【VMCloud云平台】SCCM(四)域内推送代理

继上一篇云平台完成SCCM部署篇之后&#xff0c;SCCM篇正式开始&#xff0c;今天将开始介绍SCCM为域内机器推送代理&#xff08;紫色为完成实施&#xff0c;红色为实施中&#xff09;&#xff1a; 1、 点击站点&#xff1a; 2、 右键属性&#xff0c;点击客户端安装设置&#…

Python实现决策树(Decision Tree)分类

关于决策树的简介可以参考&#xff1a; http://blog.csdn.net/fengbingchun/article/details/78880934在 https://machinelearningmastery.com/implement-decision-tree-algorithm-scratch-python/ 中给出了CART(Classification and Regression Trees,分类回归树算法,简称CART…

顶尖技术专家严选,15场前沿论坛思辨,2019中国大数据技术大会邀您共赴

扫码了解2019中国大数据技术大会&#xff08;https://t.csdnimg.cn/IaHb&#xff09;更多详情。2019中国大数据技术大会&#xff08;BDTC 2019&#xff09;将于12月5日-7日在北京长城饭店举办&#xff0c;本届大会将聚焦智能时代&#xff0c;大数据技术的发展曲线以及大数据与社…

jQuery 加法计算 使用+号即强转类型

1 var value1 $("#txt1").val(); 2 var value2 $("#txt2").val(); 3 //数值前添加号 number加号和数值加号需要用空格隔开 即实现加法运算 4 $("#txt3").val(value1 value2); 转载于:https://www.cnblogs.com/xiemin-minmin/p/11026784.…