C++多线程基础学习笔记(五)
一、互斥量
1.1 互斥量的基本概念
简单来说,一个锁就是一个互斥量,既然是锁,就有两种状态:加锁和解锁,通过加锁>>>操作共享数据>>>解锁的方式,实现保护共享数据。
1.2 互斥量的用法
作用:在给某段代码加锁后,如果其他其他线程需要先等带该段代码执行完,然后解锁后才能继续执行。
头文件 :#include <mutex>
成员函数:lock() //加锁,unlock() //解锁
注意点:lock()与unlock()的使用必须成对存在。
#include <iostream>
#include <mutex>
using namespace std;
int num = ;
mutex my_mutex; //创建一个互斥量
void print1()
{
for (int i = ; i < ; i++)
{
my_mutex.lock();
cout << "thread_1:" << num++ << endl;
my_mutex.unlock();
}
}
void print2()
{
for (int i = ; i < ; i++)
{
my_mutex.lock();
cout << "thread_2:" << num++ << endl;
my_mutex.unlock();
}
} int main()
{
thread thread_1(print1); //打印0-49
thread thread_2(print2); //打印49-99
thread_1.join();
thread_2.join();
system("pause");
return ;
}
还有一种方法,可实现加锁和解锁两个步骤,即用std::lock_guard<mutex> myguard (my_mutex)来代替lock()和unlock(),其原理是,在std::lock_guard构造函数里执行了lock(),在析构函数里执行了unlock()。
#include <iostream>
#include <mutex>
using namespace std;
int num = ;
mutex my_mutex;
void print1()
{
for (int i = ; i < ; i++)
{
lock_guard<mutex> myguard(my_mutex);
cout << "thread_1:" << num++ << endl;
}
}
void print2()
{
for (int i = ; i < ; i++)
{
lock_guard<mutex> myguard(my_mutex);
cout << "thread_2:" << num++ << endl;
}
} int main()
{
thread thread_1(print1); //打印0-49
thread thread_2(print2); //打印49-99
thread_1.join();
thread_2.join();
system("pause");
return ;
}
二、死锁
仅在存在两个互斥量以上才会出现死锁的现象。例如线程A获得了锁1,线程B获得了锁2,这时线程A调用lock试图获得锁2,结果是需要挂起等待线程B释放锁2,而这时线程B也调用lock试图获得锁1,结果是需要挂起等待线程A释放锁1,于是线程A和B都永远处于挂起状态了。通俗来讲,就是我在等你解锁我才能解锁,你在等我解锁你才能解锁。
#include <iostream>
#include <mutex>
using namespace std;
int num = ;
mutex my_mutex1;
mutex my_mutex2;
void print1()
{
for (int i = ; i < ; i++)
{
my_mutex1.lock();
/*这里同通常有一段代码,也是用来操作共享数据*/
my_mutex2.lock();
cout << "thread_1:" << num++ << endl;
my_mutex1.unlock();
my_mutex2.unlock();
}
}
void print2()
{
for (int i = ; i < ; i++)
{
my_mutex2.lock();
my_mutex1.lock();
cout << "thread_2:" << num++ << endl;
my_mutex1.unlock();
my_mutex2.unlock();
}
} int main()
{
thread thread_1(print1); //打印0-49
thread thread_2(print2); //打印49-99
thread_1.join();
thread_2.join();
system("pause");
return ;
}
运行结果发现也不会出现任何奔溃出错现象,但是就一直卡在那里,不会继续运行下去了。

解决死锁的方法其实也很简单,只要保证互斥量加锁的顺序一致就可以了。或者使用std::lock(mutex1,mutex2),意思是给这两个互斥量同时上锁。
C++多线程基础学习笔记(五)的更多相关文章
- C++基础 学习笔记五:重载之运算符重载
C++基础 学习笔记五:重载之运算符重载 什么是运算符重载 用同一个运算符完成不同的功能即同一个运算符可以有不同的功能的方法叫做运算符重载.运算符重载是静态多态性的体现. 运算符重载的规则 重载公式 ...
- java基础学习笔记五(抽象类)
java基础学习总结——抽象类 抽象类介绍
- Java基础学习笔记(五) - 常用的API
API介绍 概念:API 即应用编程程序接口.Java API是JDK中提供给我们使用的类说明文档,这些类将底层的代码实现封装.无需关心这些类是如何实现,只需要学习如何使用. 使用:通过API找到需要 ...
- Java基础学习笔记五 Java基础语法之面向对象
面向对象 理解什么是面向过程.面向对象 面向过程与面向对象都是我们编程中,编写程序的一种思维方式.面向过程的程序设计方式,是遇到一件事时,思考“我该怎么做”,然后一步步实现的过程.例如:公司打扫卫生( ...
- C++多线程基础学习笔记(四)
一.创建多个子线程 前面三章讲的例子都是只有一个子线程和主线程,然而实际中有多个子线程.那么下面介绍如何创建多个子线程. #include <iostream> #include < ...
- C++多线程基础学习笔记(一)
下面分三个方面多线程技术的必须掌握一些基本知识. 1.进程 2.线程 3.并发 (1)进程 一个可执行程序运行起来了,即为创建了一个进程.如在电脑上打开了word,就创建了一个word进程,打开QQ, ...
- loadrunner基础学习笔记五-场景
场景目标:模拟10家旅行社同时登录.搜索航班.购买机票.查看航班路线并退出 负载测试是指在典型工作条件下测试应用程序,例如:多家旅行社同时在同一个机票预订系统中预订机票 controller提供所有用 ...
- JSP的范围-作用域(web基础学习笔记五)
JSP的范围(作用域) 在JSP页面中的对象,包括用户创建的对象如JavaBean,都有一个范围属性,这个范围也被叫做“作用域”.范围定义了在什么时间内,在哪一个JSP页面中可以访问这些对象.例如,s ...
- C++多线程基础学习笔记(十)
一.Windows临界区的基本用法 CRITICAL_SECTION my_winsc; //定义一个Windows的临界区,相当于一个mutex变量 InitializeC ...
随机推荐
- codevs 2010 求后序遍历x
题目描述 Description 输入一棵二叉树的先序和中序遍历序列,输出其后序遍历序列. 输入描述 Input Description 共两行,第一行一个字符串,表示树的先序遍历,第二行一个字符串, ...
- MySQL_(Java)使用JDBC向数据库中修改(update)数据
MySQL_(Java)使用JDBC向数据库发起查询请求 传送门 MySQL_(Java)使用JDBC向数据库中插入(insert)数据 传送门 MySQL_(Java)使用JDBC向数据库中删除(d ...
- SVN如何处理包含@2x or @3x的图片文件
一般iOS图片文件都会包含@2x,@3x之类的字符比如icon@2x,icon@3x,当你在svn命令行中add或是delete的时候总是报错说file does not exit之类的错误,其实之类 ...
- ASIHTTPRequest使用
http://qk13warcraft.blog.163.com/blog/static/157549344201271633014969/ 1.创建和运行请求 创建一个同步请求 这是最简单的用法,发 ...
- canvas基础知识点(一)
给canvas设置宽高: canvas标签的宽高默认是300*150,是一个行内块元素 可以在canvas标签上通过width,height来设置 可以在js中给dom对象设置: mycanvas.w ...
- VUE中让由全局变量添加生成的新数组不随全局变量的变化而变化
问题场景: const addOptions = { singleOrComplex, totalNum: this.smallTotalPrice, selectList: this.purchas ...
- VNC Viewer配置
VNC概述 VNC (Virtual Network Computing)是虚拟网络计算机的缩写.VNC 是一款优秀的远程控制工具软件,由著名的 AT&T 的欧洲研究实验室开发的.VNC 是在 ...
- php下intval()和(int)转换使用与区别
没啥区别,一般用(int),另外还有 float, string, array 等 intval()而言,如果参数是字符串,则返回字符串中第一个不是数字的字符之前的数字串所代表的整数值.如果字符串第一 ...
- [常用的Cmd运行命令]
打开命令提示符,有很多与系统有关的命令都可以在命令提示符中完成,比如输入ipconfig查看电脑的IP osk 打开屏幕键盘 calc 打开计算器的功能 notepad 打开记事本 mspaint ...
- WebStrom编程小技巧--HTML快速创建指定id或者类名的div
打印div标签快速方法:“先打出#yz,然后Tab键补全即可获得<div id="yz"></div>同理:我们也可以先打出“.tz"然后Tab键 ...