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

embedded/2024/11/15 6:17:18/

文章目录

  • (二)线程的创建、分离和链接
    • 创建线程:示例
    • 线程的分离(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秒。


http://www.ppmy.cn/embedded/31436.html

相关文章

SpringSecurity6 学习

学习介绍 网上关于SpringSecurity的教程大部分都停留在6以前的版本 但是&#xff0c;SpringSecurity6.x版本后的内容进行大量的整改&#xff0c;网上的教程已经不能够满足 最新的版本使用。这里我查看了很多教程 发现一个宝藏课程&#xff0c;并且博主也出了一个关于SpringSec…

Leaflet在WGS84 Web墨卡托投影与WGS84经纬度投影下空间信息变形问题及修正-以圆为例

目录 前言 一、投影的相关知识 1、经纬度投影 2、Web墨卡托投影 二、经纬度投影下的空间信息展示 1、空间信息展示 2、效果展示 3、经纬度投影下的圆修正 三、Web墨卡托投影下空间信息展示 1、底图引用 2、自定义生成圆 总结 前言 在GIS的知识海洋中&#xff0c;对…

leetCode68. 文本左右对齐

基本思路&#xff1a; leetCode68. 文本左右对齐 代码 class Solution { public:vector<string> fullJustify(vector<string>& words, int maxWidth) {vector<string> res;for(int i 0; i < words.size(); i){ // 枚举有多少个单词int j i 1; //…

数学符号的标准写法 (机器学习方向)

摘要: 本贴讨论数学符号的标准写法, 列出 Latex 中使用的命令. 表 1. 矩阵相关符号 符号/操作意义Latex 命令 A \mathbf{A} A矩阵\mathbf{A} A i \mathbf{A}_{i} Ai​带下标的矩阵, 注意不是矩阵的元素 (entry)\mathbf{A}_{i} A i j \mathbf{A}_{ij} Aij​带双下标的矩阵矩阵\m…

自动化滇医通

###我已经将数据爬取出来### 现在开源集合大家的思路一起研究 &#xff08;请更换ip 以及 暂停时间 不然会提示违规操作&#xff09; 脚本读取预约信息后开始随机抢一家的&#xff0c;qiang方法里面请自行修改抓包数据参数&#xff01;&#xff01; 现在开源大家一起讨论 pyt…

深入 Django 模型层:数据库设计与 ORM 实践指南

title: 深入 Django 模型层&#xff1a;数据库设计与 ORM 实践指南 date: 2024/5/3 18:25:33 updated: 2024/5/3 18:25:33 categories: 后端开发 tags: Django ORM模型设计数据库关系性能优化数据安全查询操作模型继承 第一章&#xff1a;引言 Django是一个基于Python的开源…

谷歌更新Chrome浏览器:一键召唤Gemini聊天机器人

大家好&#xff0c;我是木易&#xff0c;一个持续关注AI领域的互联网技术产品经理&#xff0c;国内Top2本科&#xff0c;美国Top10 CS研究生&#xff0c;MBA。我坚信AI是普通人变强的“外挂”&#xff0c;所以创建了“AI信息Gap”这个公众号&#xff0c;专注于分享AI全维度知识…

vector顺序表

目录 1.vector的介绍 2.vector的定义 3.vector的迭代器 3.1begin()&#xff0c;end() 3.2rbegin(),rend() 3.3cbegin(),cend(),crbegin(),crend() 4.容量操作 4.1size() 4.2max_size() 4.3resize() 4.4capacity() 4.5empty() 4.6reverse() 4.7shirink_to_fit() 5.…