当前位置: 首页 > news >正文

【C++并发编程】(二)线程的创建、分离和连接

文章目录

  • (二)线程的创建、分离和链接
    • 创建线程:示例
    • 线程的分离(detach)和连接(join)

(二)线程的创建、分离和链接

创建线程:示例

线程(Thread)是并发执行的基本单位。在C++中,std::thread用于创建和管理线程。当你想在线程中执行某个有参数或无参数的函数时,你可以将该函数传递给std::thread创建的线程对象,以下是一些示例。

示例1:传递无参数函数

#include <iostream>
#include <thread>void print_hello() {std::cout << "Hello from thread!\n";
}int main() {// 创建一个 std::thread 类型的对象 t,并传递 print_hello作为t构造函数的参数。std::thread t(print_hello);t.join(); // 等待线程结束,下一节介绍其作用return 0;
}

示例2:传递带参数函数(拷贝)

#include <iostream>
#include <thread>void print_number(int num) {std::cout << "Number: " << num << '\n';
}int main() {int value = 42;std::thread t(print_number, value); // 创建线程,并传入参数(value 被拷贝给线程  )t.join(); // 等待线程结束return 0;
}

示例3:传递带参数函数(使用引用或指针)

如果你希望在线程中修改传入的参数值,可以用std::ref来包装参数,以便在创建线程时传递其引用。

#include <iostream>
#include <thread>void modify_number(int& num) {num *= 2;std::cout << "Modified number: " << num << '\n';
}int main() {int value = 42;std::thread t(modify_number, std::ref(value)); // 创建线程,并传入参数的引用t.join(); // 等待线程结束std::cout << "Value in main: " << value << '\n'; // 验证值已被修改return 0;
}
Modified number: 84
Value in main: 84

示例4:传递多个参数

你可以传递多个参数给线程函数。

#include <iostream>
#include <thread>void print_info(std::string name, int age) {std::cout << "Name: " << name << ", Age: " << age << '\n';
}int main() {std::string name = "Alice";int age = 30;std::thread t(print_info, name, age); // 创建线程,并传入多个参数t.join(); // 等待线程结束return 0;
}

示例5:传递类的成员函数和实例

你还可以传递类的成员函数和类的实例给线程。

#include <iostream>
#include <thread>class Person {
public:void say_hello(const std::string& greeting) {std::cout << greeting << " from " << name << '\n';}std::string name = "Bob";
};int main() {Person person;// 当线程 t 开始执行时,它会调用 person 对象的 say_hello 函数,并以 "Hello" 作为参数。std::thread t(&Person::say_hello, &person, "Hello"); // 创建线程,并传入成员函数和对象指针t.join(); // 等待线程结束return 0;
}

线程的分离(detach)和连接(join)

在C++中,线程的分离(detach)和连接(join)是用于管理线程生命周期的两种主要方式。当创建一个线程时,你可以选择让它独立运行(即分离),或者等待它完成执行(即连接)。

分离(detach)

当你调用std::thread::detach()方法时,你告诉线程库你不再关心这个线程的结束时间,并且你不需要获取它的返回值。线程将在后台独立运行,直到其函数返回,结束。

示例:

#include <iostream>  
#include <thread>  
#include <chrono>  
#include <ctime>  
#pragma warning(disable: 4996)
void thread_task() {  // 阻塞当前线程的执行,直到指定的时间间隔(2s)过去 std::this_thread::sleep_for(std::chrono::seconds(2));  auto now = std::chrono::system_clock::now();  std::time_t now_c = std::chrono::system_clock::to_time_t(now);  std::cout << "Hello from detached thread at " << std::ctime(&now_c) << std::endl;  
}  int main() {  auto start_time = std::chrono::system_clock::now();  std::time_t start_time_c = std::chrono::system_clock::to_time_t(start_time);  std::cout << "Main thread starts at " << std::ctime(&start_time_c) << std::endl;  std::thread t(thread_task); // 创建线程  t.detach(); // 分离线程  // 主线程将不会等待t的结束,而是继续执行  std::cout << "Main thread continues execution without waiting for the detached thread.\n";  // 让主线程休眠3s,以便观察分离线程的输出  std::this_thread::sleep_for(std::chrono::seconds(3));  auto end_time = std::chrono::system_clock::now();  std::time_t end_time_c = std::chrono::system_clock::to_time_t(end_time);  std::cout << "Main thread ends at " << std::ctime(&end_time_c) << std::endl;  return 0;  
}

在这个例子中,t线程将开始执行thread_task函数,并在调用t.detach()后立即返回主线程。主线程将继续执行,而不需要等待t线程的完成。

Main thread starts at Fri May  3 23:02:06 2024Main thread continues execution without waiting for the detached thread.
Hello from detached thread at Fri May  3 23:02:08 2024Main thread ends at Fri May  3 23:02:09 2024

开始和结束相差3秒。

连接(join)

当你调用std::thread::join()方法时,你告诉线程库你想要等待这个线程完成执行后再继续下去。调用join()的线程将被阻塞,直到被连接的线程执行完毕。

示例:

#include <iostream>  
#include <thread>  
#include <chrono>  
#include <ctime>  
#pragma warning(disable: 4996)
void thread_task() {  // // 休眠2sstd::this_thread::sleep_for(std::chrono::seconds(2));  auto now = std::chrono::system_clock::now();  std::time_t now_c = std::chrono::system_clock::to_time_t(now);  std::cout << "Hello from joined thread at " << std::ctime(&now_c) << std::endl;  
}  int main() {  auto start_time = std::chrono::system_clock::now();  std::time_t start_time_c = std::chrono::system_clock::to_time_t(start_time);  std::cout << "Main thread starts at " << std::ctime(&start_time_c) << std::endl;  std::thread t(thread_task); // 创建线程  // 主线程将在这里阻塞,等待t的完成  t.join();  std::cout << "Main thread continues execution after the thread is joined.\n";  std::this_thread::sleep_for(std::chrono::seconds(3));  auto end_time = std::chrono::system_clock::now();  std::time_t end_time_c = std::chrono::system_clock::to_time_t(end_time);  std::cout << "Main thread ends at " << std::ctime(&end_time_c) << std::endl;  return 0;  
}

在这个例子中,t线程将开始执行thread_task函数,而主线程在调用t.join()时将阻塞,等待t线程完成。当t线程完成后,主线程将继续执行。

Main thread starts at Fri May  3 23:11:45 2024Hello from joined thread at Fri May  3 23:11:47 2024Main thread continues execution after the thread is joined.
Main thread ends at Fri May  3 23:11:50 2024

开始和结束相差5秒。

相关文章:

【C++并发编程】(二)线程的创建、分离和连接

文章目录 &#xff08;二&#xff09;线程的创建、分离和链接创建线程&#xff1a;示例线程的分离&#xff08;detach&#xff09;和连接&#xff08;join&#xff09; &#xff08;二&#xff09;线程的创建、分离和链接 创建线程&#xff1a;示例 线程&#xff08;Thread&a…...

利用生成式AI重新构想ITSM的未来

对注入 AI 的生成式 ITSM 的需求&#xff0c;在 2023 年 Gartner AI 炒作周期中&#xff0c;生成式 AI 达到预期值达到顶峰后&#xff0c;三分之二的企业已经将生成式 AI 集成到其流程中。 你问为什么这种追求&#xff1f;在预定义算法的驱动下&#xff0c;IT 服务交付和管理中…...

完美解决AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘

遇到这种错误通常是因为matplotlib的后端配置问题。在某些环境中&#xff0c;尤其是在某些特定的IDE或Jupyter Notebook环境中&#xff0c;可能会因为后端配置不正确而导致错误。错误信息提示 module backend_interagg has no attribute FigureCanvas 意味着当前matplotlib的后…...

CMakeLists.txt语法规则:条件判断中表达式说明一

一. 简介 前面学习了 CMakeLists.txt语法中的 部分常用命令&#xff0c;常量变量&#xff0c;双引号的使用。 前面一篇文章也简单了解了 CMakeLists.txt语法中的条件判断&#xff0c;文章如下&#xff1a; CMakeLists.txt语法规则&#xff1a;条件判断说明一-CSDN博客 本文…...

《QT实用小工具·五十三》会跑走的按钮

1、概述 源码放在文章末尾 该项目实现了会逃跑的按钮&#xff1a; 两个按钮&#xff0c;一个为普通按钮&#xff0c;另一个为会跑走的按钮 鼠标移到上面时&#xff0c;立刻跑掉 针对鼠标、键盘、触屏进行优化 随机交换两个按钮的文字、偶尔钻到另一个按钮下面、鼠标移开自…...

Servlet的几种用法?

serlet 1.定义&#xff1a;Serlet是使用Java编写的运行在服务器端的程序 2.Servlet主要是用于处理浏览器端发送的Http请求&#xff0c;并返回一个响应 3.Servlet开发需要使用到的包&#xff1a; java.servlet java.servlet.http 一.Servlet注册 1.xml方式 <servlet>…...

Golang | Leetcode Golang题解之第69题x的平方根

题目&#xff1a; 题解&#xff1a; func mySqrt(x int) int {if x 0 {return 0}C, x0 : float64(x), float64(x)for {xi : 0.5 * (x0 C/x0)if math.Abs(x0 - xi) < 1e-7 {break}x0 xi}return int(x0) }...

AR人脸美妆SDK解决方案,让妆容更加贴合个人风格

美妆行业正迎来前所未有的变革&#xff0c;为满足企业对高效、精准、创新的美妆技术需求&#xff0c;美摄科技倾力打造了一款企业级AR人脸美妆SDK解决方案&#xff0c;为企业打开美妆领域的新世界大门。 革命性的人脸美妆技术 美摄科技的AR人脸美妆SDK解决方案&#xff0c;不…...

Python-100-Days: Day09 Object-oriented programming(OOP) Upgrade

1.property装饰器 之前有讨论过&#xff0c; Python中属性和方法访问权限的问题&#xff0c;不建议将属性设置为私有的&#xff0c;倘若直接将属性暴露给外界也是存在问题的。例如&#xff0c;我们没有办法检查赋给属性的值是否有效。之前的建议是将属性命名以单下划线开头&am…...

虹科Pico汽车示波器 | 免拆诊断案例 | 2010款凯迪拉克SRX车发动机无法起动

故障现象 一辆2010款凯迪拉克SRX车&#xff0c;搭载LF1发动机&#xff0c;累计行驶里程约为14.3万km。该车因正时链条断裂导致气门顶弯&#xff0c;大修发动机后试车&#xff0c;起动机运转有力&#xff0c;但发动机没有着机迹象&#xff1b;多起动几次&#xff0c;火花塞会变…...

ECC 号码总结

1、问题背景 在手机开发过程中&#xff0c;经常遇见各种紧急号码问题&#xff0c;在此特意总结下紧急号码相关知识。 2、紧急号码来源 在MTK RILD EccNumberSource.h中&#xff0c;定义了如下几种紧急号码来源。 按优先级排序介绍如下 2.1、SOURCE_NETWORK 网络下发&#xff…...

《大疆二次开发》EMQX和MQTT部署

EMQX 服务器 基础知识 概念 EMQX (Erlang/Enterprise/Elastic MQTT Broker) &#xff1b;EMQ/EMQX就是MQTT Broker的一种实现&#xff1b;一款开源的大规模分布式 MQTT 消息服务器&#xff0c;功能丰富&#xff0c;专为物联网和实时通信应用而设计&#xff1b;支持多种协议&…...

【网络】滑动窗口和拥塞窗口

滑动窗口和拥塞窗口是TCP协议中两个重要的窗口概念&#xff0c;它们分别用于流量控制和拥塞控制&#xff0c;在功能和作用上有所不同。 滑动窗口&#xff08;Sliding Window&#xff09; 滑动窗口是用于流量控制的机制&#xff0c;它定义了发送方和接收方之间的数据传输量。T…...

数据库知识初步汇总

创建标签表格&#xff1a; CREATE TABLE IF NOT EXISTS labels (标签ID INTEGER PRIMARY KEY,标签名称 TEXT );创建文本与标签的关联表格&#xff1a; CREATE TABLE IF NOT EXISTS 文本标签 (文本ID INTEGER,标签ID INTEGER,FOREIGN KEY (文本ID) REFERENCES texts(编号),FOR…...

Moby简介:openEuler 中的开源docker引擎

Moby 是一个开源的容器化引擎&#xff0c;它提供了创建和管理容器所需的核心功能。在 openEuler 系统中&#xff0c;Moby 作为容器技术的实现之一&#xff0c;它允许用户利用容器化技术来部署、运行和移植应用程序。 Moby 的功能和作用&#xff1a; 1. **容器创建**&#xff…...

分布式光纤测温DTS的测温范围是多少?

分布式光纤测温DTS的测温范围不仅仅取决于光缆的感温能力&#xff0c;还受到多种复杂因素的影响。尽管高温光缆可以耐高温&#xff0c;低温光缆可以耐低温&#xff0c;甚至镀金光缆能够耐受高达700摄氏度的极高温度&#xff0c;然而&#xff0c;这些因素并不能完全解释测温范围…...

Java实现裁剪PDF

目录 安装Java PDF库 Java裁剪PDF页面 Java裁剪PDF页面并将结果保存为图片、HTML、Excel等格式 裁剪PDF页面是一项常见的任务&#xff0c;它可以用来调整文档的尺寸和去除不需要的边距或白边。通过裁剪页面&#xff0c;你可以优化文档的布局和展示效果&#xff0c;使其更符合…...

ZooKeeper以及DolphinScheduler的用法

目录 一、ZooKeeper的介绍 数据模型 ​编辑 操作使用 ①登录客户端 ​编辑 ②可以查看下面节点有哪些 ③创建新的节点&#xff0c;并指定数据 ④查看节点内的数据 ⑤、删除节点及数据 特殊点&#xff1a; 运行机制&#xff1a; 二、DolphinScheduler的介绍 架构&#…...

gitlab集群高可用架构拆分部署

目录 前言 负载均衡器准备 外部负载均衡器 内部负载均衡器 (可选)Consul服务 Postgresql拆分 1.准备postgresql集群 手动安装postgresql插件 2./etc/gitlab/gitlab.rb配置 3.生效配置文件 Redis拆分 1./etc/gitlab/gitlab.rb配置 2.生效配置文件 Gitaly拆分 1.…...

STC8增强型单片机开发day01

C51版本Keil环境搭建 搭建流程 环境搭建的基本流程&#xff1a; 从官方网站下载并安装Keil软件。选择安装的软件中的C51工具集并运行。通过从“文件”菜单中选择“项目”来创建新项目。输入项目名称并选择您正在使用的设备。通过从“项目”菜单中选择“添加文件到组”来添加…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

R语言AI模型部署方案:精准离线运行详解

R语言AI模型部署方案:精准离线运行详解 一、项目概述 本文将构建一个完整的R语言AI部署解决方案,实现鸢尾花分类模型的训练、保存、离线部署和预测功能。核心特点: 100%离线运行能力自包含环境依赖生产级错误处理跨平台兼容性模型版本管理# 文件结构说明 Iris_AI_Deployme…...

java 实现excel文件转pdf | 无水印 | 无限制

文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

系统设计 --- MongoDB亿级数据查询优化策略

系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log&#xff0c;共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题&#xff0c;不能使用ELK只能使用…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

现代密码学 | 椭圆曲线密码学—附py代码

Elliptic Curve Cryptography 椭圆曲线密码学&#xff08;ECC&#xff09;是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础&#xff0c;例如椭圆曲线数字签…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...