【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++并发编程】(二)线程的创建、分离和连接
文章目录 (二)线程的创建、分离和链接创建线程:示例线程的分离(detach)和连接(join) (二)线程的创建、分离和链接 创建线程:示例 线程(Thread&a…...

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

完美解决AttributeError: module ‘backend_interagg‘ has no attribute ‘FigureCanvas‘
遇到这种错误通常是因为matplotlib的后端配置问题。在某些环境中,尤其是在某些特定的IDE或Jupyter Notebook环境中,可能会因为后端配置不正确而导致错误。错误信息提示 module backend_interagg has no attribute FigureCanvas 意味着当前matplotlib的后…...
CMakeLists.txt语法规则:条件判断中表达式说明一
一. 简介 前面学习了 CMakeLists.txt语法中的 部分常用命令,常量变量,双引号的使用。 前面一篇文章也简单了解了 CMakeLists.txt语法中的条件判断,文章如下: CMakeLists.txt语法规则:条件判断说明一-CSDN博客 本文…...

《QT实用小工具·五十三》会跑走的按钮
1、概述 源码放在文章末尾 该项目实现了会逃跑的按钮: 两个按钮,一个为普通按钮,另一个为会跑走的按钮 鼠标移到上面时,立刻跑掉 针对鼠标、键盘、触屏进行优化 随机交换两个按钮的文字、偶尔钻到另一个按钮下面、鼠标移开自…...
Servlet的几种用法?
serlet 1.定义:Serlet是使用Java编写的运行在服务器端的程序 2.Servlet主要是用于处理浏览器端发送的Http请求,并返回一个响应 3.Servlet开发需要使用到的包: java.servlet java.servlet.http 一.Servlet注册 1.xml方式 <servlet>…...

Golang | Leetcode Golang题解之第69题x的平方根
题目: 题解: 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解决方案,让妆容更加贴合个人风格
美妆行业正迎来前所未有的变革,为满足企业对高效、精准、创新的美妆技术需求,美摄科技倾力打造了一款企业级AR人脸美妆SDK解决方案,为企业打开美妆领域的新世界大门。 革命性的人脸美妆技术 美摄科技的AR人脸美妆SDK解决方案,不…...

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

虹科Pico汽车示波器 | 免拆诊断案例 | 2010款凯迪拉克SRX车发动机无法起动
故障现象 一辆2010款凯迪拉克SRX车,搭载LF1发动机,累计行驶里程约为14.3万km。该车因正时链条断裂导致气门顶弯,大修发动机后试车,起动机运转有力,但发动机没有着机迹象;多起动几次,火花塞会变…...

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

《大疆二次开发》EMQX和MQTT部署
EMQX 服务器 基础知识 概念 EMQX (Erlang/Enterprise/Elastic MQTT Broker) ;EMQ/EMQX就是MQTT Broker的一种实现;一款开源的大规模分布式 MQTT 消息服务器,功能丰富,专为物联网和实时通信应用而设计;支持多种协议&…...
【网络】滑动窗口和拥塞窗口
滑动窗口和拥塞窗口是TCP协议中两个重要的窗口概念,它们分别用于流量控制和拥塞控制,在功能和作用上有所不同。 滑动窗口(Sliding Window) 滑动窗口是用于流量控制的机制,它定义了发送方和接收方之间的数据传输量。T…...
数据库知识初步汇总
创建标签表格: CREATE TABLE IF NOT EXISTS labels (标签ID INTEGER PRIMARY KEY,标签名称 TEXT );创建文本与标签的关联表格: CREATE TABLE IF NOT EXISTS 文本标签 (文本ID INTEGER,标签ID INTEGER,FOREIGN KEY (文本ID) REFERENCES texts(编号),FOR…...
Moby简介:openEuler 中的开源docker引擎
Moby 是一个开源的容器化引擎,它提供了创建和管理容器所需的核心功能。在 openEuler 系统中,Moby 作为容器技术的实现之一,它允许用户利用容器化技术来部署、运行和移植应用程序。 Moby 的功能和作用: 1. **容器创建**ÿ…...

分布式光纤测温DTS的测温范围是多少?
分布式光纤测温DTS的测温范围不仅仅取决于光缆的感温能力,还受到多种复杂因素的影响。尽管高温光缆可以耐高温,低温光缆可以耐低温,甚至镀金光缆能够耐受高达700摄氏度的极高温度,然而,这些因素并不能完全解释测温范围…...
Java实现裁剪PDF
目录 安装Java PDF库 Java裁剪PDF页面 Java裁剪PDF页面并将结果保存为图片、HTML、Excel等格式 裁剪PDF页面是一项常见的任务,它可以用来调整文档的尺寸和去除不需要的边距或白边。通过裁剪页面,你可以优化文档的布局和展示效果,使其更符合…...

ZooKeeper以及DolphinScheduler的用法
目录 一、ZooKeeper的介绍 数据模型 编辑 操作使用 ①登录客户端 编辑 ②可以查看下面节点有哪些 ③创建新的节点,并指定数据 ④查看节点内的数据 ⑤、删除节点及数据 特殊点: 运行机制: 二、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环境搭建 搭建流程 环境搭建的基本流程: 从官方网站下载并安装Keil软件。选择安装的软件中的C51工具集并运行。通过从“文件”菜单中选择“项目”来创建新项目。输入项目名称并选择您正在使用的设备。通过从“项目”菜单中选择“添加文件到组”来添加…...

Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...

GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
jmeter聚合报告中参数详解
sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample(样本数) 表示测试中发送的请求数量,即测试执行了多少次请求。 单位,以个或者次数表示。 示例:…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现企业微信功能
1. 开发环境准备 安装DevEco Studio 3.1: 从华为开发者官网下载最新版DevEco Studio安装HarmonyOS 5.0 SDK 项目配置: // module.json5 {"module": {"requestPermissions": [{"name": "ohos.permis…...

Chrome 浏览器前端与客户端双向通信实战
Chrome 前端(即页面 JS / Web UI)与客户端(C 后端)的交互机制,是 Chromium 架构中非常核心的一环。下面我将按常见场景,从通道、流程、技术栈几个角度做一套完整的分析,特别适合你这种在分析和改…...

Ubuntu系统复制(U盘-电脑硬盘)
所需环境 电脑自带硬盘:1块 (1T) U盘1:Ubuntu系统引导盘(用于“U盘2”复制到“电脑自带硬盘”) U盘2:Ubuntu系统盘(1T,用于被复制) !!!建议“电脑…...
6️⃣Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙
Go 语言中的哈希、加密与序列化:通往区块链世界的钥匙 一、前言:离区块链还有多远? 区块链听起来可能遥不可及,似乎是只有密码学专家和资深工程师才能涉足的领域。但事实上,构建一个区块链的核心并不复杂,尤其当你已经掌握了一门系统编程语言,比如 Go。 要真正理解区…...

QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...