c/c++ 多线程 unique_lock的使用
多线程 unique_lock的使用
unique_lock的特点:
1,灵活。可以在创建unique_lock的实例时,不锁,然后手动调用lock_a.lock()函数,或者std::lock(lock_a, …),来上锁。当unique_lock的实例被析构时,会自动调用unlock函数,释放锁。
unique_lock<mutex> lock_a(d1.m, std::defer_lock);
2,unique_lock的实例可以调用unlock函数。这个意味着,在unique_lock的实例销毁前,你可以有选择的在程序的分支释放锁。持有锁的时间比所需时间更长,可能会导致性能下降,因为其他等待该锁的线程,被阻止运行的时间超过了所需的时间。
注意:有个弊端,当不拥有锁的时候,调用了unlock成员方法,程序崩溃。崩溃信息如下:
terminate called after throwing an instance of 'std::system_error'
what(): Operation not permitted
Aborted (core dumped)
3,可以在作用域之间转移锁的所有权。右值的话,会自动被转移;左值的话,必须手动调用std::move()函数,来进行锁的所有权的转移。
通常使用这种模式,是在待锁定的互斥元依赖于程序的当前状态,或者依赖于传递给返回std::unique_lock对象的函数的地方。
例子:关于上述第一点和第二点的
#include <list>
#include <iostream>
#include <mutex>
#include <algorithm>
#include <thread>
#include <unistd.h>
using namespace std;
class data_protect;
void swap(data_protect& , data_protect& );
//是线程安全的
class data_protect{
friend void swap(data_protect& , data_protect& );
private:
list<int> alist{1,2};
mutex m;
public:
void add_list(int val){
//操作双向链表时,加锁了
lock_guard<mutex> g(m);
alist.push_back(val);
}
bool contains(int val){
//操作双向链表时,加锁了
lock_guard<mutex> g(m);
return find(alist.begin(), alist.end(), val) != alist.end();
}
};
void swap(data_protect& d1, data_protect& d2){
//if(d1 == d2) return;
//造成死锁
//d1.add_list(11);
unique_lock<mutex> lock_a(d1.m, std::defer_lock);
unique_lock<mutex> lock_b(d2.m, std::defer_lock);
std::lock(lock_a, lock_b);
swap(d1.alist, d2.alist);
//有unlock成员函数,并可以手动调用unlock函数
//如果没有持有锁,就调用unlock成员函数就会导致程序崩溃。所以要检查是否拥有锁。
if(lock_a.owns_lock() && lock_b.owns_lock()){
lock_a.unlock();
lock_b.unlock();
}
}
int main(){
data_protect d1, d2;
swap(d1, d2);
d2.add_list(11);
}
例子:关于上述的第三点
#include <mutex>
std::unique_lock<std::mutex> getlock(){
std::mutex sm;
std::unique_lock<std::mutex> lk(sm);
//prepare_data();
return lk;//因为lk是右值,所以自动调用了std::move函数,把锁的所有权转移了出去。
}
void process_data(){
std::unique_lock<std::mutex> lk(getlock());
//do_something();
}
int main(){
process_data();
}
github源代码
c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854
c/c++ 多线程 unique_lock的使用的更多相关文章
- C++11 std::unique_lock与std::lock_guard区别及多线程应用实例
C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为.通常的做法是在修改共享数据成员的时候进行加锁--mutex.在使用锁的时候通 ...
- C++ 11 多线程下std::unique_lock与std::lock_guard的区别和用法
这里主要介绍std::unique_lock与std::lock_guard的区别用法 先说简单的 一.std::lock_guard的用法 std::lock_guard其实就是简单的RAII封装, ...
- C++11并发——多线程lock_gurad ,unique_lock (三)
http://www.cnblogs.com/haippy/p/3346477.html struct defer_lock_t {}; 该类型的常量对象 defer_lock(defer_lock ...
- C++并发与多线程学习笔记--unique_lock详解
unique_lock 取代lock_quard unique_lock 的第二个参数 std::adopt_lock std::try_to_lock std::defer_lock unique_ ...
- 多线程05:unique_lock详解
unique_lock详解 一.unique_lock取代lock_guard unique_lock是个类模板,实际应用中,一般lock_guard(推荐使用):lock_guard取代了mutex ...
- Java多线程 3 线程同步
在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的 ...
- c++并发练习---多线程顺序打印
参考:http://blog.csdn.net/liuxuejiang158blog/article/details/22061267 题目:编写一个程序,开启3个线程,这3个线程的ID分别为A.B. ...
- shared_ptr和多线程
前一篇文章写得实在太挫,重新来一篇. 多线程环境下生命周期的管理 多线程环境下,跨线程对象的生命周期管理会有什么挑战?我们拿生产者消费者模型来讨论这个问题. 实现一个简单的用于生产者消费者模型的队列 ...
- c++ unique_lock lock_guard
unique_lock template <class Mutex> class unique_lock; Unique lock A unique lock is an object t ...
随机推荐
- 关于Python pandas模块输出每行中间省略号问题
关于Python数据分析中pandas模块在输出的时候,每行的中间会有省略号出现,和行与行中间的省略号....问题,其他的站点(百度)中的大部分都是瞎写,根本就是复制黏贴以前的版本,你要想知道其他问题 ...
- 本地连接虚拟机_环境搭建01_VMWARE/XShell/CentOS
今天起准备搭建一套环境用来学习redis,dubbo,docker,nginx. 环境准备: 1.VMware12: https://pan.baidu.com/s/1-LnqfrWw8ZjQdmG ...
- redis 系列20 服务器下
二. serverCron函数 2.3 更新服务器每秒执行命令次数 serverCron函数中的trackOperationsPerSecond函数会以每100毫秒一次的频率执行,这个函数以抽样计算的 ...
- Python爬虫入门教程 18-100 煎蛋网XXOO图片抓取
写在前面 很高兴我这系列的文章写道第18篇了,今天写一个爬虫爱好者特别喜欢的网站煎蛋网http://jandan.net/ooxx,这个网站其实还是有点意思的,网站很多人写了N多的教程了,各种方式的都 ...
- 线程安全(上)--彻底搞懂volatile关键字
对于volatile这个关键字,相信很多朋友都听说过,甚至使用过,这个关键字虽然字面上理解起来比较简单,但是要用好起来却不是一件容易的事.这篇文章将从多个方面来讲解volatile,让你对它更加理解. ...
- leetcode — remove-duplicates-from-sorted-list
/** * Source : https://oj.leetcode.com/problems/remove-duplicates-from-sorted-list/ * * * Given a so ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(7)- 反汇编文件(.s/.lst/.dump)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的反汇编文件(.s, .lst, .dump). 痞子衡在第四.五.六节课分别介绍了编译器/链接器生成的3种output文件( ...
- 痞子衡嵌入式:第一本Git命令教程(6)- 日志(log/reflog/gitk)
今天是Git系列课程第六课,上一课我们学会了Git本地提交,今天痞子衡要讲的是如何查看Git本地历史提交. 当我们在仓库里做了很多次提交之后,免不了需要回看提交记录,看看自己之前的改动.有三种Git命 ...
- 重复造轮子,编写一个轻量级的异步写日志的实用工具类(LogAsyncWriter)
一说到写日志,大家可能推荐一堆的开源日志框架,如:Log4Net.NLog,这些日志框架确实也不错,比较强大也比较灵活,但也正因为又强大又灵活,导致我们使用他们时需要引用一些DLL,同时还要学习各种用 ...
- 认识RabbitMQ交换机模型
前言 RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工作虽然有用到,但是却没有形成很好的整体包括,主要是一些基础概念的认识,这里通过阅读<Rabbi ...