C++使用thread类进行多线程编程
C++11中引入了一个用于多线程操作的thread类,简单多线程示例:
#include <iostream>
#include <thread>
#include <Windows.h>
using namespace std;
void thread01()
{
for (int i = 0; i < 5; i++)
{
cout << "Thread 01 is working !" << endl;
Sleep(100);
}
}
void thread02()
{
for (int i = 0; i < 5; i++)
{
cout << "Thread 02 is working !" << endl;
Sleep(200);
}
}
int main()
{
thread task01(thread01);
thread task02(thread02);
task01.join();
task02.join();
for (int i = 0; i < 5; i++)
{
cout << "Main thread is working !" << endl;
Sleep(200);
}
system("pause");
}
输出:
两个子线程并行执行,join函数会阻塞主流程,所以子线程都执行完成之后才继续执行主线程。可以使用detach将子线程从主流程中分离,独立运行,不会阻塞主线程:
#include <iostream>
#include <thread>
#include <Windows.h>
using namespace std;
void thread01()
{
for (int i = 0; i < 5; i++)
{
cout << "Thread 01 is working !" << endl;
Sleep(100);
}
}
void thread02()
{
for (int i = 0; i < 5; i++)
{
cout << "Thread 02 is working !" << endl;
Sleep(200);
}
}
int main()
{
thread task01(thread01);
thread task02(thread02);
task01.detach();
task02.detach();
for (int i = 0; i < 5; i++)
{
cout << "Main thread is working !" << endl;
Sleep(200);
}
system("pause");
}
输出:
使用detach的主线程和两个子线程并行执行。
带参子线程
在绑定的时候也可以同时给带参数的线程传入参数:
#include <iostream>
#include <thread>
#include <Windows.h>
using namespace std;
//定义带参数子线程
void thread01(int num)
{
for (int i = 0; i < num; i++)
{
cout << "Thread 01 is working !" << endl;
Sleep(100);
}
}
void thread02(int num)
{
for (int i = 0; i < num; i++)
{
cout << "Thread 02 is working !" << endl;
Sleep(200);
}
}
int main()
{
thread task01(thread01, 5); //带参数子线程
thread task02(thread02, 5);
task01.detach();
task02.detach();
for (int i = 0; i < 5; i++)
{
cout << "Main thread is working !" << endl;
Sleep(200);
}
system("pause");
}
输出跟上例输出一样:
多线程数据竞争
多个线程同时对同一变量进行操作的时候,如果不对变量做一些保护处理,有可能导致处理结果异常:
#include <iostream>
#include <thread>
#include <Windows.h>
using namespace std;
int totalNum = 100;
void thread01()
{
while (totalNum > 0)
{
cout << totalNum << endl;
totalNum--;
Sleep(100);
}
}
void thread02()
{
while (totalNum > 0)
{
cout << totalNum << endl;
totalNum--;
Sleep(100);
}
}
int main()
{
thread task01(thread01);
thread task02(thread02);
task01.detach();
task02.detach();
system("pause");
}
输出结果(部分):
有两个问题,一是有很多变量被重复输出了,而有的变量没有被输出;二是正常情况下每个线程输出的数据后应该紧跟一个换行符,但这里大部分却是另一个线程的输出。
这是由于第一个线程对变量操作的过程中,第二个线程也对同一个变量进行各操作,导致第一个线程处理完后的输出有可能是线程二操作的结果。
针对这种数据竞争的情况,可以使用线程互斥对象mutex保持数据同步。
mutex类的使用需要包含头文件mutex:
#include <iostream>
#include <thread>
#include <Windows.h>
#include <mutex>
using namespace std;
mutex mu; //线程互斥对象
int totalNum = 100;
void thread01()
{
while (totalNum > 0)
{
mu.lock(); //同步数据锁
cout << totalNum << endl;
totalNum--;
Sleep(100);
mu.unlock(); //解除锁定
}
}
void thread02()
{
while (totalNum > 0)
{
mu.lock();
cout << totalNum << endl;
totalNum--;
Sleep(100);
mu.unlock();
}
}
int main()
{
thread task01(thread01);
thread task02(thread02);
task01.detach();
task02.detach();
system("pause");
}
多线程中加入mutex互斥对象之后输出正常:
后记:
C++11之前,Windows系统为我们提供了相关API,我们可以使用他们来进行多线程编程。
C++使用thread类进行多线程编程的更多相关文章
- 继承Thread类使用多线程
java实现多线程有两种方式,一种是继承Thread类,另外一种就是实现Runnable接口. 两种实现方法的优缺点: 使用Thread类实现多线程局限性就是不支持多继承,因为java是不支持类多继承 ...
- 多线程之继承Thread类及多线程内存分析
*创建多线程的一种方式:继承Thread类 * java.lang.Thread是描述多线程的类,要实现多线程程序,一种方式就是继承Thread类 * 1.创建一个类Mythread让其extends ...
- thread模块—Python多线程编程
Thread 模块 *注:在实际使用过程中不建议使用 thread 进行多线程编程,本文档只为学习(或熟悉)多线程使用. Thread 模块除了派生线程外,还提供了基本的同步数据结构,称为锁对象(lo ...
- 通过继承Thread类实现多线程
(1)继承Thread类(2)重写run(方法(3)通过start0方法启动线程 一定的缺点: Java中的类是单继承的,一旦继承了Thread类,就不允许再去继承其它的类 线程和主方法之间的执行顺序 ...
- java多线程同步以及线程间通信详解&消费者生产者模式&死锁&Thread.join()(多线程编程之二)
本篇我们将讨论以下知识点: 1.线程同步问题的产生 什么是线程同步问题,我们先来看一段卖票系统的代码,然后再分析这个问题: package com.zejian.test; /** * @author ...
- 探Java多线程Thread类和Runnable接口之间的联系
首先复习一下Java多线程实现机制,Java实现多线程方法有如下这么几种: 1.继承了(extends)Thread类 2.实现了(implements)Runnable接口 也就是说 有如下两种情 ...
- 多线程编程(三)--创建线程之Thread VS Runnable
前面写过一篇基础的创建多线程的博文: 那么本篇博文主要来对照一下这两种创建线程的差别. 继承Thread类: 还拿上篇博客的样例来说: 四个线程各自卖各自的票,说明四个线程之间没有共享,是独立的线程. ...
- Java通过继承thread类与实现Runnable接口实现多线程的区别
Java中线程的创建有两种方式: 1. 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2. 通过实现Runnable接口,实例化Thread类 一.通过继承T ...
- Java 多线程实现方式一:继承Thread类
java 通过继承Thread类实现多线程很多简单: 只需要重写run方法即可. 比如我们分三个线程去京东下载三张图片: 1.先写个下载类: 注意导入CommonsIO 包 public class ...
随机推荐
- highchart 柱状图,单个样例
var chart = Highcharts.chart('container', { chart: { type: 'column' }, title: { text: '月平均气温' }, sub ...
- [转载]css代码优化的12个技巧
1.ID 规则2.Class 规则3.标签规则4.通用规则对效率的普遍认识是从Steve Souders在2009年出版的<高性能网站建设进阶指南>开始,虽然该书中罗列的更加详细,但你也可 ...
- 每日linux命令学习-rpm命令
rpm命令 rpm是一款强大的Redhat软件包管理工具,可创建.安装.查询.验证.升级和卸载每个软件包,软件包是存储文件,包括需要安装的文件和名称.版本.说明等报信息. rpm默认支持7种操作模式, ...
- 再论sklearn分类器
https://www.cnblogs.com/hhh5460/p/5132203.html 这几天在看 sklearn 的文档,发现他的分类器有很多,这里做一些简略的记录. 大致可以将这些分类器分成 ...
- laravel 数据库 - 增删查改
//查询public function select(){ /** 数据表 CREATE TABLE `student` ( `id` int(11) NOT NULL AUTO_INCREMENT, ...
- pyqt5 界面切换
QStackedWidget 只需要关联好对应的信号和槽,调用setCurrentIndex函数,想切哪个界面就切到哪个界面
- 2016 icpc ECfinal && codeforcesgym101194
一不小心惨变旅游队,不过上海的风景不错 顺带找其他队交流一下集训经验...或许可以成为选拔和集训16级的依据 A.直接模3就可以了,2^(3*n)%7=1 C.Mr. Panda and Strips ...
- roon
http://www.sthifi.com/Article/ViewArticle.asp?id=10895 http://kb.roonlabs.com/LinuxInstall https://c ...
- 树莓派无显示器开启ssh的方法
在boot根目录新建一个名为 ssh 的空文件即可. boot目录所在分区是fat32格式,可以被windows识别和操作 带有系统的tf卡(或SD卡)插入读卡器中,新建ssh文件即可,注意无后缀名
- 【题解】Luogu P2572 [SCOI2010]序列操作
原题传送门:P2572 [SCOI2010]序列操作 这题好弱智啊 裸的珂朵莉树 前置芝士:珂朵莉树 窝博客里对珂朵莉树的介绍 没什么好说的自己看看吧 操作1:把区间内所有数推平成0,珂朵莉树基本操作 ...