C++线程操作

C++线程操作

定义

std::thread必须明确调用join()detach(),否则程序终止时会调用std::terminate()

特性 std::thread std::jthread
引入标准 C++11 C++20
资源管理 析构时若仍可汇合(joinable)会‌调用std::terminate终止程序 析构时若仍可汇合,会‌**自动调用join()**‌,等待线程结束
协作中断 不支持‌ 原生协作中断机制 支持 ‌,通过 request_stop() 请求停止,线程内可查询停止状态
成员函数 join(), detach(), get_id(), joinable() 包含std::thread所有功能,并增加 request_stop(), get_stop_source(), get_stop_token()
推荐使用 旧代码维护,或需要手动控制线程生命周期 新项目首选‌,更安全,资源管理更自动化
cpp 复制代码
void sayHello() {
	std::this_thread::sleep_for(std::chrono::seconds(3));
	std::cout << getStringFromU8string(u8"Hello World,子线程, threadId=") + getThreadIdAsString() + "\n";
}


int main()
{
	system("chcp 65001");
	std::cout << getStringFromU8string(u8"开始主线程,threadId=") << std::this_thread::get_id() << endl;


	std::thread thread1(sayHello);
	//std::jthread thread2(sayHello);

	// thread必须显式调用
	// thread1.join();
	// 
	// jthread会自动调用join方法
	//thread2.join();

	std::cout << getStringFromU8string(u8"结束主线程,threadId=") << std::this_thread::get_id() << endl;
	return 0;
}

构造函数

1、通过函数指针

带返回值的函数,需要用到其他方式

cpp 复制代码
#include <iostream>
#include <string>
#include <thread>

using namespace std;
std::string getStringFromU8string(const std::u8string& u8str) {
	return std::string(reinterpret_cast<const char*>(u8str.data()), u8str.size());
}

std::u8string getU8stingFromString(const std::string& str) {
	return std::u8string(reinterpret_cast<const char8_t*>(str.data()), str.size());
}


void sayHello() {
	std::cout << getStringFromU8string(u8"Hello World,子线程, threadId=") << std::this_thread::get_id() << endl;
}

void add(int a, int b) {
	std::cout << getStringFromU8string(u8"Hello World,子线程, threadId=") << std::this_thread::get_id() << " ;a+b=" << (a + b) << endl;
}


int main()
{
	system("chcp 65001");
	std::cout << getStringFromU8string(u8"开始主线程,threadId=") << std::this_thread::get_id() << endl;

	// 无参,无返回
	std::thread thread1(sayHello);
	// 有参,无返回
	std::thread thread2(add, 2, 3);

	// 等待线程结束(阻塞主线程)
	thread1.join();
	thread2.join();

	std::cout << getStringFromU8string(u8"结束主线程,threadId=") << std::this_thread::get_id() << endl;
	return 0;
}

2、通过Lambda 表达式

cpp 复制代码
int main()
{
	system("chcp 65001");
	std::cout << getStringFromU8string(u8"开始主线程,threadId=") << std::this_thread::get_id() << endl;

	// 无参,无返回
	std::thread thread1([]() {std::cout << getStringFromU8string(u8"Hello World,子线程, threadId=") << std::this_thread::get_id() << endl; });
	// 有参,无返回
	std::thread thread2([](int a, int b) {std::cout << getStringFromU8string(u8"Hello World,子线程, threadId=") << std::this_thread::get_id() << " ;a+b=" << (a + b) << endl; }, 2, 3);

	// 等待线程结束(阻塞主线程)
	thread1.join();
	thread2.join();

	std::cout << getStringFromU8string(u8"结束主线程,threadId=") << std::this_thread::get_id() << endl;
	return 0;
}

3、通过成员函数

cpp 复制代码
#include <iostream>
#include <string>
#include <thread>
#include <sstream>

using namespace std;
std::string getStringFromU8string(const std::u8string& u8str) {
	return std::string(reinterpret_cast<const char*>(u8str.data()), u8str.size());
}

std::u8string getU8stingFromString(const std::string& str) {
	return std::u8string(reinterpret_cast<const char8_t*>(str.data()), str.size());
}

std::string getThreadIdAsString() {
	std::stringstream ss;
	ss << std::this_thread::get_id();
	return ss.str();
}

class Hello {
public:
	void sayHello() {
		std::cout << getStringFromU8string(u8"Hello World,子线程, threadId=") + getThreadIdAsString() + "\n";
	}

	void add(int a, int b) {
		std::cout << getStringFromU8string(u8"Hello World,子线程, threadId=") + getThreadIdAsString() + " ;a+b=" + std::to_string(a + b) + "\n";
	}

	static void staticAdd(int a, int b) {
		std::cout << getStringFromU8string(u8"Hello World,子线程, threadId=") + getThreadIdAsString() + " ;a+b=" + std::to_string(a + b) + "\n";
	}
};


int main()
{
	system("chcp 65001");
	std::cout << getStringFromU8string(u8"开始主线程,threadId=") << std::this_thread::get_id() << endl;
	Hello hello;

	// 无参,无返回
	std::thread thread1(&Hello::sayHello, &hello);
	// 有参,无返回
	std::thread thread2(&Hello::add, &hello, 2, 3);
	// 有参,无返回(静态方法)
	std::thread thread3(&Hello::staticAdd, 5, 6);

	// 等待线程结束(阻塞主线程)
	thread1.join();
	thread2.join();
	thread3.join();

	std::cout << getStringFromU8string(u8"结束主线程,threadId=") << std::this_thread::get_id() << endl;
	return 0;
}

4、拷贝构造函数

已删除,不支持

5、移动构造函数

cpp 复制代码
int main()
{
	system("chcp 65001");
	std::cout << getStringFromU8string(u8"开始主线程,threadId=") << std::this_thread::get_id() << endl;
	Hello hello;

	std::thread thread1(&Hello::sayHello, &hello);
	// 移动构造函数,原thread1失效不可用了
	std::thread thread2(std::move(thread1));

	// 等待线程结束(阻塞主线程)
	// thread1.join();
	thread2.join();

	std::cout << getStringFromU8string(u8"结束主线程,threadId=") << std::this_thread::get_id() << endl;
	return 0;
}
相关推荐
txinyu的博客3 分钟前
map和unordered_map的性能对比
开发语言·数据结构·c++·算法·哈希算法·散列表
mjhcsp28 分钟前
C++ 后缀数组(SA):原理、实现与应用全解析
java·开发语言·c++·后缀数组sa
hui函数29 分钟前
如何解决 pip install 编译报错 ‘cl.exe’ not found(缺少 VS C++ 工具集)问题
开发语言·c++·pip
码农小韩1 小时前
基于Linux的C++学习——循环
linux·c语言·开发语言·c++·算法
消失的旧时光-19431 小时前
C++ 命名空间 namespace 讲透:从 std:: 到工程实践
开发语言·c++
linweidong1 小时前
C++ 中避免悬挂引用的企业策略有哪些?
java·jvm·c++
CoderCodingNo1 小时前
【GESP】C++五级/四级练习(双指针/数学) luogu-P1147 连续自然数和
开发语言·c++·算法
Q741_1471 小时前
海致星图招聘 数据库内核研发实习生 一轮笔试 总结复盘(2) 作答语言:C/C++ 哈夫曼编码 LRU
c语言·数据库·c++·算法·笔试·哈夫曼编码·哈夫曼树
Z1Jxxx1 小时前
日期日期日期
开发语言·c++·算法
报错小能手2 小时前
nginx集群聊天室(一) 初步讲解集群聊天室所需库的搭建
c++·nginx