c++并发编程(二)——管理线程 thread类

本文详细介绍C++中线程的创建、管理及资源安全转移的方法。从std::thread对象的构造到线程函数参数传递,再到线程所有权的转移,深入浅出地讲解了线程管理的核心技术。并通过实例演示了如何使用RAII(资源获取即初始化)来确保线程安全地结束。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

启动线程

同上节所讲,线程是通过构造std::thread对象来开始的:

void do_some_work();
std::thread my_thread(do_some_work);

使用可调用类型:

#include<iostream>
#include<thread>

class func {

public:
	void operator()() {
		std::cout << "hello thread" << std::endl;
	}
};


int main() {

	func fun;
	std::thread t(fun);
	t.join();

	system("pause");

}

等待线程完成

如果你不做处理,在主线程结束后,thread对象管理的线程也被结束了,通过调用thread.detach()使线程不被销毁,或使用join()使主线程等待其他线程的结束。

使用RAII(资源获取即初始化)等待线程完成:

#include<iostream>
#include<windows.h>
#include<thread>


class func {

public:
	void operator()() {
		Sleep(1000);
		std::cout << "hello thread" << std::endl;
	}
};

class thread_guard {
	std::thread& t;
public:
	explicit thread_guard(std::thread& t_) :t(t_) {}
	~thread_guard() {
		if (t.joinable()) {
			t.join();
		}
	}
};

int main() {

	func fun;
	std::thread t(fun);
	thread_guard g(t);

	system("pause");
	return 0;
}

传递参数给线程函数

使用std::ref()包装需要引用的参数:

void f(int i, int& j) {
	i++;
	j++;
}

int main() {
	int i = 10;
	int j = 10;
	std::thread t(f,i,std::ref(j));
	t.join();
	std::cout << "i:" << i << std::endl
		<< "j:" << j << std::endl;                 //输出i:10  j:11

	system("pause");
	return 0;
}

转移线程的所有权

同其他拥有资源的类型(std:;ifstream和std::unique_ptr)一样std::thread是可移动的非可复制的

以下改进thread_guard类,使它实际上获得线程的所有权,这就能避免其他对象结合或分离该线程:

class scoped_thread
{
	std::thread t;
public:
	explicit scoped_thread(std::thread t_)
		: t(std::move(t_))
	{
		if (!t.joinable())
		{
			throw std::logic_error("No thread");
		}
	}
	~scoped_thread()
	{
		t.join();
	}
	scoped_thread(scoped_thread&) = delete;
	scoped_thread& operator=(scoped_thread const &) = delete;
};

void fun() {
	std::cout << std::this_thread::get_id() << std::endl;
}

int main()
{

	scoped_thread tt(std::thread{ fun });     //这里使用大括号而不是小括号来避免c++将其视为函数声明
											  
	//scoped_thread t(std::thread([]          //也可以使用lambda表达式来避免
	//{
	//	std::cout << std::this_thread::get_id() << std::endl;
	//}));

	system("pause");
	return 0;
}

其他

//获取机器真正并行线程数指标,信息不可用则返回0
std::cout << std::thread::hardware_concurrency() << std::endl; 

//获取线程标识
//1、当前线程的标识符
std::this_thread::get_id()
//2、通过线程对象的成员函数获得
t.get_id()

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值