线程管理基础

本文详细介绍了C++中线程的启动、线程启动后的操作、如何传递参数、线程所有权转移以及线程的识别,特别强调了线程安全和资源管理的重要性,提供了多种示例来解释线程管理的关键概念。
摘要由CSDN通过智能技术生成

线程的启动

线程在以初始函数(新线程的入口)构造std::thread对象时启动,换句话说,合理的构造std::thread即启动线程

(注意:以无参构造函数构造的std::thread对象并不启动线程)

 

构造std::thread对象的三种方式

使用普通函数构造

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

使用可调用对象构造

class background_task
{
 public:
	void operator()() const
	{
		do_something();
		do_something_else();
	}
};
background_task f;
std::thread my_thread(f);


使用类成员函数与类对象构造

class Test
{ 
public:
	void testFunc();
};
Test myTest;
std::thread t(&Test::testFunc, &myTest);

注意:

1、使用以函数对象构造std::thread对象的方式时,需要注意避免直接传递临时对象(直接调用类的构造函数时产生的对象),因为当传递临时对象时,C++编译器会将其解析为函数声明,而不是类对象的定义,因此不会启动线程

std::thread my_thread(background_task());	//被视为声明一个参数为函数指针且返回值为std::thread对象的函数

解决方案

1)、使用命名对象而不是直接传递临时对象

background_task f;
std::thread my_thread(f);


2)、使用多组括号

std::thread my_thread( (background_task()) );	//额外的一对括号

3)、使用C++11新特性,同一初始化语法

std::thread my_thread{ background_task() };	//大括号

4)、使用C++11新特性lambda表达式

std::thread my_thread( []{ 	//捕获列表为空
do_something();			//参数列表与返回值类型为空
do_something_else();		//函数体为两个函数的调用
} );

Lambda表达式表示一个可调用的代码单元(像函数对象一样的可调用对象),可以将其理解为未命名的内联函数

 

线程启动之后

线程在启动之后我们可以对其选择两种操作:

1、使用join()明确等待线程结束(加入式)(有点像pthread_join())

2、使用detach()让其自主运行(分离式)(有点像pthread_detach())

 

注意

1、在std::thread对象析构之前,无论是分离还是加入,必须为其选择一种操作,否则程序就会终止(std::thread对象的析构函数会调用std::terminate()函数)

2、如果线程已经结束(指线程入口函数全部执行完毕),再去分离它,线程(线程入口函数)可能会在std::thread对象销毁后继续运行下去(测试发现并不是这样,或许没碰到我期望的可能吧

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值