多线程 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);
}

github源代码

例子:关于上述的第三点

#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的使用的更多相关文章

  1. C++11 std::unique_lock与std::lock_guard区别及多线程应用实例

    C++多线程编程中通常会对共享的数据进行写保护,以防止多线程在对共享数据成员进行读写时造成资源争抢导致程序出现未定义的行为.通常的做法是在修改共享数据成员的时候进行加锁--mutex.在使用锁的时候通 ...

  2. C++ 11 多线程下std::unique_lock与std::lock_guard的区别和用法

    这里主要介绍std::unique_lock与std::lock_guard的区别用法 先说简单的 一.std::lock_guard的用法 std::lock_guard其实就是简单的RAII封装, ...

  3. C++11并发——多线程lock_gurad ,unique_lock (三)

    http://www.cnblogs.com/haippy/p/3346477.html struct defer_lock_t {}; 该类型的常量对象 defer_lock(defer_lock ...

  4. C++并发与多线程学习笔记--unique_lock详解

    unique_lock 取代lock_quard unique_lock 的第二个参数 std::adopt_lock std::try_to_lock std::defer_lock unique_ ...

  5. 多线程05:unique_lock详解

    unique_lock详解 一.unique_lock取代lock_guard unique_lock是个类模板,实际应用中,一般lock_guard(推荐使用):lock_guard取代了mutex ...

  6. Java多线程 3 线程同步

    在之前,已经学习到了线程的创建和状态控制,但是每个线程之间几乎都没有什么太大的联系.可是有的时候,可能存在多个线程多同一个数据进行操作,这样,可能就会引用各种奇怪的问题.现在就来学习多线程对数据访问的 ...

  7. c++并发练习---多线程顺序打印

    参考:http://blog.csdn.net/liuxuejiang158blog/article/details/22061267 题目:编写一个程序,开启3个线程,这3个线程的ID分别为A.B. ...

  8. shared_ptr和多线程

    前一篇文章写得实在太挫,重新来一篇. 多线程环境下生命周期的管理 多线程环境下,跨线程对象的生命周期管理会有什么挑战?我们拿生产者消费者模型来讨论这个问题. 实现一个简单的用于生产者消费者模型的队列 ...

  9. c++ unique_lock lock_guard

    unique_lock template <class Mutex> class unique_lock; Unique lock A unique lock is an object t ...

随机推荐

  1. MyBatis 处理关系运算符

    MyBatis mapper文件是xml文件,使用关系运算符需要进行转义. 关系运算符 转义后字符 < < <= <= > > > >=

  2. 解决classNotFound的问题的思路

    用Ctrl+Shift+t可以查看class,对于报错信息,我们把没有找到的class放到查找框里进行查看,找到之后把这个jar包放到WEB-INF的lib目录下,build path一下就可以了. ...

  3. 花10分钟搞懂开源框架吧 - 【NancyFx.Net】

    NancyFx是什么? Nancy是一个轻量级的独立的框架,下面是官网的一些介绍: Nancy 是一个轻量级用于构建基于 HTTP 的 Web 服务,基于 .NET 和 Mono 平台,框架的目标是保 ...

  4. 设计模式的征途(C#实现)—文章目录索引

    1.预备篇 UML类图10分钟快速入门 2.创建型模式 ① 设计模式的征途-01.单例(Singleton)模式 ② 设计模式的征途-02.简单工厂(Simple Factory)模式 ③ 设计模式的 ...

  5. [Python Web]部署完网站需要做的基本后续工作

    简述 今天自己上线了一个简单的 Page,没有什么功能就是一个展示页. 但是,我发现部署完,上线后,还要弄不少东西.下面就是我记录.整理的一些上线网站基本都会用到的网站和配置. 加入统计代码 这个是必 ...

  6. OKR与Scrum如何强强联手

    我们收到很多问题询问如何把OKR和其他框架结合起来使用,以便管理组织的人员.流程和活动. 软件开发公司最喜欢用的框架之一就是Scrum,Scrum是一个诞生于20世纪90年代的软件开发框架,我们公司内 ...

  7. Python爬虫实例:爬取豆瓣Top250

    入门第一个爬虫一般都是爬这个,实在是太简单.用了 requests 和 bs4 库. 1.检查网页元素,提取所需要的信息并保存.这个用 bs4 就可以,前面的文章中已经有详细的用法阐述. 2.找到下一 ...

  8. 初学Java Web(5)——cookie-session学习

    HTTP 协议 Web 浏览器与 Web 服务器之间的一问一答的交互过程必须遵守一定的规则,这样的规则就是 HTTP 协议. HTTP 是 hypertext transfer protocol(超文 ...

  9. Tomcat多实例部署

    前言 以前总是采用很Low的方式太同一台服务器上部署多个Web应用,步骤是这样的:Copy Tomcat目录-->更改conf/server.xml三个端口号----->部署war包--- ...

  10. springboot(五)过滤器和拦截器

    前言 过滤器和拦截器二者都是AOP编程思想的提现,都能实现诸如权限检查.日志记录等.二者有一定的相似之处,不同的地方在于: Filter是servlet规范,只能用在Web程序中,而拦截器是Sprin ...