#include <future>
#include <mutex>
#include <iostream>
#include <string>
#include <exception>
#include <stdio.h>
using namespace std; mutex printMutex;
static string s = "Hello from a first thread";
void print()
{
try{
cout << "thread start:" << this_thread::get_id() << endl;
lock_guard<mutex> l(printMutex);//它只能保证你的thread不能并发(在printMutex没有释放前,它可以阻塞其他的调用),但是后面的s数据可以被改变
/*这样的lock应该被限制在可能之最短周期内,因为它们会阻塞(block)其他代码的并行运行机会。由于析构
函数会释放这个lock,你或许会想明确安插大括号,令lock在更近一步语句被处理前先被释放*/
for (char c : s)
{
this_thread::sleep_for(chrono::milliseconds());
cout.put(c);
}
cout << endl;
}
catch (const exception& e)
{
cerr << "EXCEPTION: " << e.what() << endl;
}
} int main()
{
try{ auto f1 = async(launch::async, print);
s = "Hello from a second thread";
auto f2 = async(launch::async, print);
this_thread::sleep_for(chrono::milliseconds());
s = "Hello from the main thread";
print();
}
catch (const exception& e)
{
cerr << "EXCEPTION: " << e.what() << " On Main " << endl;
}
system("pause");
return ;
}

有时候我们会遇到这种情况:

当我们定义一个类,我们定义了private 的mutex 变量。并且在类里的函数中进行了锁定(lock_guard<mutex>lg(变量))。当我们在某个函数中进行锁定mutex 变量,并且我们在其后面调用了我们有锁定变量的类函数。

这样会造成死锁的情况出现。因为我们已经锁住了mutex 变量,但是后面的语句中我们还要锁定mutex 变量,所以第二次锁定的mutex 变量要等待第一次mutex 变量解锁,但是该函数没有运行完第一次锁定的mutex 变量不会被析构函数将这个lock释放掉,所以线程一直在等待,造成死锁。

解决方案:我们可以使用recursive_mutex 来进行定义mutex变量。

recursive_mutex允许同一线程多次锁定,并在最近的一次(last)相应的unlock时释放lock。

Mutex 和 Lock的更多相关文章

  1. 关于boost的thread的mutex与lock的问题

    妈的,看了好久的相关的知识,感觉终于自己有点明白了,我一定要记下来啊,相关的知识呀.... 1, 也可以看一下boost的线程指南:http://wenku.baidu.com/link?url=E_ ...

  2. boost库中thread多线程详解2——mutex与lock

    1. mutex对象类 mutex类主要有两种:独占式与共享式的互斥量.▲ 独占式互斥量:mutex: 独占式的互斥量,是最简单最常用的一种互斥量类型try_mutex: 它是mutex的同义词,为了 ...

  3. 第29课 互斥量与自解锁(std::mutex和lock系列)

    一. 互斥量 (一)Mutex系列类 1. std::mutex:独占的互斥量,不能递归使用. 2. std::recursive_mutex:递归互斥量.允许同一线程多次获得该互斥锁,可以用来解决同 ...

  4. Mutex,Monitor,lock,MethodImplAttribute,SynchronizedAttribute的用法差异

    1)Mutex:进程之间的同步(互斥量). 2)lock/Monitor……:线程同步.其中lock是Monitor的简化版本(直接生成try{Monitor.Enter(……)}finally{Mo ...

  5. 线程系列08,实现线程锁的各种方式,使用lock,Montor,Mutex,Semaphore以及线程死锁

    当涉及到多线程共享数据,需要数据同步的时候,就可以考虑使用线程锁了.本篇体验线程锁的各种用法以及线程死锁.主要包括: ※ 使用lock处理数据同步※ 使用Monitor.Enter和Monitor.E ...

  6. C#线程/进程同步(lock、Mutex、Semaphore)

    一.lock(实质是Monitor.Enter和Monitor.Exit)(线程同步) 二.Mutex(互斥量)(线程/进程同步) Mutex有个好的特性是,如果程序结束时而互斥锁没通过Release ...

  7. Thread and shared lock

    在看programing python 4th,第5张parallel system tool 192页开始,书中讲到thread知识,以下做个笔记,以便后期学习 1.主线程执行,开启5个子线程进行计 ...

  8. C++开发过程多线程同步lock的实现

    在程序开发过程经常使用到多线程,而多线程始终与锁存在紧密地联系,以下详细的介绍如何在C++程序开发过程中自定义锁的几种方法. 1. 下面给出一段代码展现如何通过Mutex实现锁的功能(window p ...

  9. C++11 并发指南三(Lock 详解)

    在 <C++11 并发指南三(std::mutex 详解)>一文中我们主要介绍了 C++11 标准中的互斥量(Mutex),并简单介绍了一下两种锁类型.本节将详细介绍一下 C++11 标准 ...

随机推荐

  1. unity5.3 安卓广告插件打包出错的理解

    今天打包带广告插件的安卓包,出现了问题 ,上网找了很多解决的办法.整理一下. 1,有的说法是unity5的BUG  因为同一个项目 用unity4.6打包就没问题 到5就出问题,当然 姑且可以这么认为 ...

  2. Python学习笔记之条件、循环和其他语句

    一.函数导入 1.为模块提供别名 >>> import math as foobar #设置math 别名为foobar >>> foobar.sqrt(4) 显示 ...

  3. JavaWeb前端:JQuery

    Jquery基本概念 什么是Jquery Jquery是一个开源的,集成了Javascript,CSS,DOM,AJAX的前端框架:它诞生于2006年,最初是为了简化JavaScript开发而产生的, ...

  4. 批量转换编码 (gbk -> utf8)

    使用 Notepad++ 批量的转换文件编码:Mass convert a project to UTF-8 using Notepad++ 步骤如下: 1.一般 Noptepad++ 安装完后已经自 ...

  5. python类中super()和__init__()的区别

    class Base(object):     def __init__(self): print 'Base create' class childB(Base): def __init__(sel ...

  6. org.apache.catalina.webresources.Cache.getResource Unable to add the resource

    org.apache.catalina.webresources.Cache.getResource Unable to add the resource at xxx to the cache be ...

  7. Intellij Idea 编辑器使用之 安装、破解 版本15.0.1

    工欲善其事必先利其器. 早就听说了Intellij idea 这个编辑器.也曾尝试过,由于对eclipse,myeclipse用的比较习惯.顺手了,所以对于Intellij idea 也只是浅尝辄止. ...

  8. sql数据库表被锁,无法查询

    查看被锁表:   select   request_session_id   spid,OBJECT_NAME(resource_associated_entity_id) tableName    ...

  9. 数据类型和Json格式(转载)

    作者: 阮一峰 日期: 2009年5月30日 1. 前几天,我才知道有一种简化的数据交换格式,叫做yaml. 我翻了一遍它的文档,看懂的地方不多,但是有一句话令我茅塞顿开. 它说,从结构上看,所有的数 ...

  10. 自己不懂的SQL语句用法

    left  join:是SQL语言中的查询类型,即连接查询.它的全称为左外连接,是外连接的一种. 连接通常可以在select语句的from子句或where子句中建立,其语法格式为: select  c ...