线程安全、C++多线程的管理(detach、join、get_id)

线程安全

线程安全函数:当一个函数被多个并发线程反复调用的时候,它的结果始终是正确的

一般线程不安全的情况,是由于同一个进程的不同线程共享进程内存空间中的全局/静态存储区和堆,如果一个函数中包含全局变量和静态变量,那么可能会线程不安全,导致程序错误。但是如果对全局变量和静态变量的操作只有读,没有修改的话,也可以将这个函数看做是线程安全的。


C++多线程(C++11)

多线程demo

C++11的标准库,提供了多线程库,需要 #include <thread> 头文件(主要提供对线程管理的类std::thread

#include <iostream>
#include <thread>
using namespace std;

void output(int i){
	cout << i << endl;
}

int main(){
	for(uint8_t i = 0; i < 8; i++)	{
		thread th(output, i);
		th.detach();	//detach表示该线程可以在后台运行,无需等待当前线程完成,会继续执行后面的操作
	}
	getchar();
	
	return 0;
}

输出结果:
在这里插入图片描述
输出的结果与预期有较大的差别。

分析:

创建了8个进程,每个进程都会调用output方法,output的过程分两步:①打印出i的值、②打印换行

涉及到多线程最核心的问题:资源竞争

8核CPU创建了8个线程,但是控制台只有1个,并且在同一时刻只能有一个线程占有这个唯一的控制台。

所以会出现情况:在一个线程占用控制台打印数字之后,没来得及打印换行,控制台就被另一个进程占用的情况。

C++11中的两种等待线程结束的方式:

detach方式,启动的线程自主在后台运行,当前的代码继续往下执行,不用等待进程结束。创建的新进程同时并发执行。
join方式会阻塞当前的代码,需要等待当前启动的线程执行完成,才会继续进行下一步。

使用join方式修改之前的demo

#include <iostream>
#include <thread>
#include <sstream>
using namespace std;

void output(int i){
	cout << i << endl;
}

int main(){
	stringstream ss;
	for(int i = 0; i < 8; i++)	{
		thread th(output, i);
		ss << "(" << th.get_id() << "): ";	//通过get_id获取线程的id 
		cout << ss.str();
		ss.str("");	//释放ss的缓冲区 
		th.join();
	}
	
	return 0;
}

//用thread的实例调用get_id()来获取线程的标识

运行结果如下:
在这里插入图片描述

通过使用join,阻塞的方式来使当前线程执行完毕后,下一个线程再开始执行。

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值