C++:std::thread:线程用法

news2024/11/26 4:37:16

1:std::thread的基本用法

最简单的 std::thread用法如下,调用 thread将立即同时开始执行这个新建立的线程,新线程的任务执行完毕之后, main()的主线程也会继续执行。

#include<iostream>
#include<thread>
#include<windows.h>
#include<string>
using namespace std;

void myfunc_work() {
	cout << "myfunc_work ....." << endl;
	// do something 5s 
	Sleep(5000);
}

int main() {
	std::thread t1(myfunc_work);
	// 阻塞当前main主线程,待子线程执行完毕后,自己恢复主线程逻辑
	t1.join();
	cout << "main thread ....." << endl;

}

2:std:: thread常用的成员函数 

下面为C++  std::thread常用的成员函数

get_id()    取得目前的线程 id, 回传一个 std::thread::id  类型

joinable()    检查是否可 join

join()   // 阻塞当前线程,等待子线程执行完毕

detach()  // 与该线程分离,一旦该线程执行完后它所分配的资源就会被释放

native_handle()    取得平台原生的 native handle.

sleep_for()    // 停止目前线程一段指定的时间

yield()   // 暂时放弃CPU一段时间,让给其他线程

void foo() {
	cout << "foo\n";
}

void bar(int x) {
	cout << "bar\n";
}

int main() {
	//std::thread t1(myfunc_work);
	//cout << "main thread ....." << endl;
	 阻塞当前main主线程,待子线程执行完毕后,自己恢复主线程逻辑
	//t1.join();
	
	thread t1(foo);
	thread t2(bar, 10);
	cout << "main,foo,bar execute concurrently....\n";

	cout << "sleep 1s\n";
	this_thread::sleep_for(chrono::seconds(2));

	cout << "join t1\n";
	t1.join();
	cout << "join t2\n";
	t2.join();

	cout << "foo and bar thread complete";

}

很显然:新线程建立后,是否立即执行新线程业务代码,有一定的随机性。

但是我们可以通过 thread.join()  或者 sleep_for() 来控制代码执行顺序 

3:建立新 thread执行类别中的函数 

C++ std::thread 的构建可以传入class类别中的成员函数,如下范例所示:AA::start 分别建立t1, t2 两个线程,而 t1传入 AA::a1 类别函数。

notice : 

     第一个参数:AA::a1 前面需要添加 & 

     第二个参数:代表的是那个类对象

     后面参数: 按照要求传入即可

class AA
{
public:
	void a1()
	{
		cout << "a1\n";
	}

	void a2(int n) {
		cout << "a2 : " << n << "\n";
	}

	void start() {
		thread t1(&AA::a1, this);
		thread t2(&AA::a2, this,10);

		t1.join();
		t2.join();
	}

private:

};

4:建立新 thread 执行 lambda expression 

std:: thread 的构建也可以传入 lambda expression 表达式,如下范例:

5:join等待thread执行结束

在main主线程建立 t1线程后,主线程便继续往下执行,如果主线程需要等待 t1执行完毕后才能继续执行的话,就需要使用 join 。

等待 t1线程执行完 foo 后主线程才能继续执行,如果 t1线程没有执行完,主线程会一致阻塞在 join这一行。

void test2() {
	cout << "foo begin...." << endl;
	this_thread::sleep_for(chrono::milliseconds(5000));
	cout << "foo end...." << endl;
}


int main() {
	std::thread t1(test2);
	cout << "main 1....." << endl;;
	t1.join();
	cout << "main 2.....";


	cout << "main thread run over" << endl;
}

6:detach不等待 thread执行结束 

承上例:如果主线程不想等或者可以不用等待 t1线程,可以使用 detach来让 t1线程分离,接着主线程就可以继续执行,t1线程 也在继续执行。

/**
	join等待thread执行结束
*/
void test2() {
	cout << "foo begin...." << endl;
	this_thread::sleep_for(chrono::milliseconds(50));
	cout << "foo end...." << endl;
}

int main() {
	
	std::thread t1(test2);
	cout << "main 1....." << endl;;
	t1.detach();
	cout << "main 2....."<< endl;


	cout << "main thread run over" << endl;
	Sleep(2000);
	return 0;
}

7:std::thread 参数传递使用引用的方法

定义方法:

void  myFunc(int&  n) {

        std::cout << "myFunc  n = " << n << endl;

        n+= 10;

}

使用参数传递使用引用目的是: 希望建立另外一个线程去执行 myFunc , 之后需要取得这个 myFunc的运算结果,但是建立线程如果写: std::thread t1(myFunc , n)  这样会编译出错。

因为在 std::thread 的参数传递方式为值传递,值传递是不可修改的左值,如果要让其能修改,可以考虑通过 : std::ref 来达成。

void myFunc(int n) {
	std::cout << "myFunc n = " << n << endl;
	n += 10;
}

void myFunc_ref(int& n) {
	std::cout << "myFunc reference n = " << n << endl;
	n += 10;
}

int main() {

	int n1 = 5;
	thread t1(myFunc, n1);
	t1.join();
	cout << "main n1 = " << n1 << "\n";

	int n2 = 10;
	thread t2(myFunc_ref, std::ref(n2));
	t2.join();
	cout << "main n2 = " << n2 << "\n";

	cout << "main thread run over" << endl;
	return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/143642.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一致性hash算法和hash算法的区别和使用场景

1、hash算法使用场景 一般情况下hash算法主要用于&#xff1a;负载均衡&#xff08;nginx 请求转发&#xff0c;scg路由等&#xff09;&#xff0c;分布式缓存分区&#xff0c;数据库分库分表&#xff08;mycat&#xff0c;shardingSphere&#xff09;等。 2、hash算法大致实…

网络编程套接字——udp网络编程

目录 一、预备知识 1.端口 2.TCP协议和UDP协议 3.socket编程接口 ①socket 常见API ②sockaddr结构 二、网络编程 1.UDP网络程序 1.1服务器 ①打印 ②socket​编辑 ③bind ④recvfrom ​编辑 1.2客户端 ①sendto 1.3提升通信的花样性 ①将字符串返还 …

Individual Tree Segmentation Method Based on Mobile Backpack LiDAR Point Clouds

Abstract 单棵树 (IT) 分割对于森林管理、支持森林清查、生物量监测或树木竞争分析至关重要。光探测和测距 (LiDAR) 是这方面的一项突出技术&#xff0c;优于竞争技术。航空激光扫描 (ALS) 经常用于森林记录&#xff0c;在树顶表面显示良好的点密度。尽管使用多回波 ALS 可以收…

【虹科云展厅专题】虹科赋能汽车智能化云展厅——车载以太网/TSN专题

虹科2023年开年福利来了&#xff01; 聚焦前沿技术&#xff0c;【虹科赋能汽车智能化云展厅】正式上线&#xff0c;本次云展厅围绕“汽车以太网/TSN、汽车总线、智能网联、电子测试与验证、自动驾驶”等核心话题&#xff0c;为您带来如临展会现场般的讲演与介绍&#xff0c;更…

Unity入门基础语法

物体的坐标 transform.position 世界坐标 transform.localPosition 相对坐标 设置物体的坐标&#xff1a; this.transform.localPosition new Vector3(1.5f, 0, 2.0f); 帧更新 Update()&#xff0c;称为帧更新 此方法会被游戏引擎定时调用&#xff0c;已更新游戏的状态 …

基于Java+SpringBoot+vue+element实现物流管理系统

基于JavaSpringBootvueelement实现物流管理系统 博主介绍&#xff1a;5年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 超级帅帅吴 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系…

SQL Studio:一款纯Web化SQL开发工具,关键是免安装还免费!

经常使用SQL工具的开发者对Navicat一定都不陌生。这款软件作为一款全球化的多数据库管理工具&#xff0c;这些年逐步得到全国各地SQLer&#xff08;SQL开发者&#xff09;的关注。 与其他很多外来的软件产品一样&#xff0c;由于价格原因&#xff0c;很多SQLer感觉不太适合适应…

聊聊微服务架构中的用户认证方案

传统的用户认证方案 我们直奔主题&#xff0c;什么是用户认证呢&#xff1f;对于大多数与用户相关的操作&#xff0c;软件系统首先要确认用户的身份&#xff0c;因此会提供一个用户登录功能。用户输入用户名、密码等信息&#xff0c;后台系统对其进行校验的操作就是用户认证。…

S7-1200与三菱FX5U系列PLC通过简单CPU通信功能实现以太网通信的具体方法

S7-1200与三菱FX5U系列PLC通过简单CPU通信功能实现以太网通信的具体方法 前提条件: 西门子S7-1200一侧需要在防护安全中选择连接机制,选择连接机制后在将这里面的“ 允许来自远程对象的PUT/GET通讯访问”这个选项勾选即可。 另外要注意,被访问的DB块要设置为非优化的块访问…

Go第 9 章:map

Go第 9 章&#xff1a;map 9.1 map 的基本介绍 map 是 key-value 数据结构&#xff0c;又称为字段或者关联数组。类似其它编程语言的集合&#xff0c; 在编程中是经常使用到 9.2 map 的声明 9.2.1基本语法 var map 变量名 map[keytype]valuetype 9.2.2map 声明的举例 m…

如果这都不是爱!谷歌承包广告牌喊话苹果;亚马逊裁员的业内分析;李玟VR演唱会明日上线;AMD发布会全程高能;GitHub今日热榜 | ShowMeAI资讯日报

&#x1f3a1; 『Google』再次买下大幅电子广告牌&#xff0c;喊话苹果推动 RCS 发展 一线消息&#xff0c;Google 在拉斯维加斯 Harmon Corner 投放了大型新年主题广告&#xff0c;喊话说服苹果采用 RCS 消息协议&#xff0c;不要在修复像素化的照片和视频上掉链子。视频显示…

YOLOv5-C3模块实现

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f366; 参考文章地址&#xff1a; 365天深度学习训练营-第P8周&#xff1a;YOLOv5-C3模块实现&#x1f356; 作者&#xff1a;K同学啊一、前期准备1.设置GPUimport torch from torch import nn i…

数据库,计算机网络、操作系统刷题笔记26

数据库&#xff0c;计算机网络、操作系统刷题笔记26 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle…

消息队列如何保证消息幂等性消费

1 介绍 我们实际系统中有很多操作&#xff0c;不管你执行多少次&#xff0c;都应该产生一样的效果或返回一样的结果。 例如&#xff1a; 前端页面重复提交选中的数据&#xff0c;服务端只产生对应这个数据的一个反应结果&#xff0c;只保存一次数据。我们发起一笔付款请求&am…

裸露土堆智能识别检测系统 yolo

裸露土堆智能识别检测系统基于pythonyolo计算机视觉深度学习技术&#xff0c;对现场画面中土堆裸露情况进行实时分析检测&#xff0c;若发现画面中的土堆有超过40%部分裸露&#xff0c;则判定为裸露进行抓拍预警。我们选择当下YOLO最新的卷积神经网络YOLOv5来进行裸露土堆识别检…

商用密码安全性评估

商用密码应用安全性评估&#xff08;简称“密评”&#xff09;指在采用商用密码技术、产品和服务集成建设的网络和信息系统中&#xff0c;对其密码应用的合规性、正确性和有效性等进行评估。01办理依据 GM/T0054-2018《信息系统密码应用基本要求》 《信息系统密码测评要求&…

Linux内核内存分配函数kmalloc、kzalloc和vmalloc

在内核环境中&#xff0c;常用的内存分配函数主要有kmalloc、kzalloc和vmalloc这三个。既然这三函数都能在内核申请空间&#xff0c;那么这三个函数有什么区别呢&#xff1f;如何选用呢&#xff1f; kmalloc 首先是kmalloc&#xff0c;其函数原型为 // /include/linux/slab.…

acwing基础课——质数

由数据范围反推算法复杂度以及算法内容 - AcWing 常用代码模板4——数学知识 - AcWing 基本思想&#xff1a; 首先&#xff0c;我们给出质数的定义&#xff0c;指在大于1的自然数中&#xff0c;除了1和该数自身外&#xff0c;无法被其他自然数整除的数。这里考虑三个问题&…

笔记-鼠标悬浮展示图标

鼠标悬浮展示图标 .primaryLink {color: primary-color-dark;}.primaryLink:hover {cursor: pointer;color: link-hover-color-dark;}.itemAction {display: none; }.itemMenu:hover .itemAction {display: block; }

【数据结构进阶】并查集

并查集 正如它的名字一样&#xff0c;并查集&#xff08;Union-Find&#xff09;就是用来对集合进行 合并&#xff08;Union&#xff09; 与 查询&#xff08;Find&#xff09; 操作的一种数据结构。 合并 就是将两个不相交的集合合并成一个集合。 查询 就是查询两个元素是否属…