c/c++ 多线程 mutex的理解
多线程 mutex的理解
mutex,我的理解是每个mutex对象都是一个带锁头的门,这个门有两个状态,门开着和门关着,感觉像是废话。。。
当想查看门的里东西,或者把东西放进门里,或者从门里拿出东西前,都需要看看,门是否是打开的。
- 如果门是打开的,就要进去后赶紧把门关上。关上后,就可以查看屋子里的东西,放东西到屋子里,从屋子里拿东西。
- 如果门是关着的,就要在外面等着,直到有人出来时,把门打开了,你才能进去。
每个mutex都是不同的门,当你用mutex a锁上了一个门,就只能用mutex a去打开,用mutex b是打不开,切记。
例子:用mutex a锁门,用metex b去开门,结果没打开,就导致了程序的死锁。
注意:这个程序专门为了测试,mutex的问题。
#include <list>
#include <iostream>
#include <mutex>
#include <algorithm>
#include <thread>
#include <unistd.h>
using namespace std;
class data_protect{
public:
list<int> alist{1,2};
mutex m;
mutex m1;
public:
void add_list(int val){
m.lock(); //----------------①
alist.push_back(val);
}
bool contains(int val){
m1.unlock();//----------------------②
return find(alist.begin(), alist.end(), val) != alist.end();
}
};
void func(data_protect& dp){
dp.add_list(12);
}
int main(){
data_protect dp;
thread t(func, ref(dp));
//t.join();
t.detach();//---------------③
//sleep(1);
dp.add_list(12);//----------------④
if(dp.contains(12)){//------------------⑤
cout << "contains 12" << endl;
}
for(auto& s : dp.alist){
cout << s << endl;
}
pthread_exit(NULL);
}
执行结果:死锁,程序永远在等待锁的打开。
执行结果分析:
从③处开始就开了一个新的线程a,线程a调用了add_list()方法,add_list方法里,在①处是用m去上的锁。main函数线程在④处也调用了,add_list()方法,进去后,发现是上锁的状态,所以就阻塞在哪里,等着锁打开后,main函数线程好进去,然后在⑤处调用了contains方法,contains方法试图在②处用m1去解m的锁,所以就解不开①处的锁,所以就导致了一个线程一直等在①处的锁的地方,就导致了死锁。
如果把②处的m1.unlock();换成m.unlock();就能解开锁了,就不会导致死锁。
想说明的东西,用哪个mutex上的锁,就得用哪个mutex去解锁。
mutex的正确使用方法:不是直接用调用mutex的lock,unlock方法。理由是在lock和unlock中间的某段代码如果崩溃掉,就会导致unlock方法没有被执行,也就导致了,锁没有解开,别线程再来访问时,就变成了死锁。
所以使用:std::lock_guard<std::mutex>,它的好处是,即使发生了异常也能自动解锁。
例子:
#include <list>
#include <iostream>
#include <mutex>
#include <algorithm>
#include <thread>
#include <unistd.h>
using namespace std;
class data_protect{
public:
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 func(data_protect& dp){
dp.add_list(12);
}
int main(){
data_protect dp;
thread t(func, ref(dp));
//t.join();
t.detach();
//sleep(1);
dp.add_list(12);
if(dp.contains(12)){
cout << "contains 12" << endl;
}
for(auto& s : dp.alist){
cout << s << endl;
}
pthread_exit(NULL);
}
c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854
c/c++ 多线程 mutex的理解的更多相关文章
- 多线程系列之 java多线程的个人理解(二)
前言:上一篇多线程系列之 java多线程的个人理解(一) 讲到了线程.进程.多线程的基本概念,以及多线程在java中的基本实现方式,本篇主要接着上一篇继续讲述多线程在实际项目中的应用以及遇到的诸多问题 ...
- cpu个数、核数、线程数、Java多线程关系的理解
cpu个数.核数.线程数.Java多线程关系的理解 2017年12月08日 15:35:37 一 cpu个数.核数.线程数的关系 cpu个数:是指物理上,也及硬件上的核心数: 核数:是逻辑上的,简单理 ...
- 我对java多进程多线程的浅显理解
linux内核调度算法--CPU时间片如何分配: http://blog.csdn.net/russell_tao/article/details/7103012(转载) ,通过该文章我们知道了进程 ...
- POSIX 多线程编程及理解
最近开发基于ZYNQ的嵌入式linux程序,涉及到多线程使用,将一些内容整理如下: POSIX多线程编程最为基础和重要的可以分为两部分: 线程操作-Thread Management 线程同步-Syn ...
- iOS 多线程的简单理解(4) 线程锁的简单使用
要用到多线程 ,就不得不考虑,线程之间的交互,线程是否安全 推荐一个原文链接 是关于 线程锁的基本使用的 http://blog.csdn.net/qq_30513483/article/detai ...
- 多线程锁--怎么理解Condition
在java.util.concurrent包中,有两个很特殊的工具类,Condition和ReentrantLock,使用过的人都知道,ReentrantLock(重入锁)是jdk的concurren ...
- iOS开发中GCD在多线程方面的理解
GCD为Grand Central Dispatch的缩写. Grand Central Dispatch (GCD)是Apple开发的一个多核编程的较新的解决方法.在Mac OS X 10.6雪豹中 ...
- 多线程系列之 Java多线程的个人理解(一)
前言:多线程常常是程序员面试时会被问到的问题之一,也会被面试官用来衡量应聘者的编程思维和能力的重要参考指标:无论是在工作中还是在应对面试时,多线程都是一个绕不过去的话题.本文重点围绕多线程,借助Jav ...
- c# 多线程 --Mutex(互斥锁)
互斥锁(Mutex) 互斥锁是一个互斥的同步对象,意味着同一时间有且仅有一个线程可以获取它. 互斥锁可适用于一个共享资源每次只能被一个线程访问的情况 函数: //创建一个处于未获取状态的互斥锁 Pub ...
随机推荐
- dedecms搜索模板,使用{dede:list}标签调用自定义字段不显示(空白)
前几天使用织梦做一个搜索功能,正常使用{dede:list}调用自定义内容模型中的自定义字段,代码如下:(自定义字段的调用可以参考:http://www.dede58.com/a/dedejq/523 ...
- Python内置函数(36)——iter
英文文档: iter(object[, sentinel]) Return an iterator object. The first argument is interpreted very dif ...
- RabbitMQ消息队列(十四)-启用SSL安全通讯
如果RabbitMQ服务在内网中,只有内网的应用连接,我们认为这些连接都是安全的,但是个别情况我们需要让RabbitMQ对外提供服务.这种情况有两种解决方案: 在RabbitMQ外层在封装一层应用,应 ...
- 痞子衡嵌入式:史上最强ARM Cortex-M学习资源汇总(持续更新中...)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是ARM Cortex-M学习资源. 类别 资源 版本 短评 官方汇总 cortex-m-resources / ARM公司专家Josep ...
- mongoDB连接数据库
package mongod; import java.util.List; import java.util.ArrayList; import org.bson.types.*; import c ...
- Java开发笔记(五十九)Java8之后的扩展接口
前面介绍了接口的基本用法,有心的朋友可能注意到这么一句话“在Java8以前,接口内部的所有方法都必须是抽象方法”,如此说来,在Java8之后,接口的内部方法也可能不是抽象方法了吗?之所以Java8对接 ...
- phpstudy等php本地环境运行缓慢的问题解决方法
我们经常会使用些一键安装包部署本地服务器环境.比如phpstudy.但是会有不少人发现,wordpress等使用数据库的程序打开或者切换页面的速度明显低于静态站点.甚至需要好几秒.这个问题一直困扰了我 ...
- jsonp promise 封装
import originJsonp from 'jsonp' export default function jsonp(url, data, option) { url += (url.index ...
- SDOI 2018划水记
Day0 最后一天啦,此时不颓更待何时? 上午10:15坐车从gryz出发,在一路颓废中到了农大 不得不说,农大的宾馆真的好高档啊,壁橱里面居然有保险柜!电视柜厨子里居然有冰箱!!冰箱里居然有饮料!! ...
- DIV中文字换行显示
居然第一次遇到这种问题,还想了半天到底是怎么回事,为什么明明div设置宽度了,里面的文字超过宽度后居然不换行. (1)word-break属性,可以让浏览器实现在任意位置换行. normal:使用浏览 ...