线程启动、结束,创建线程多法、join,detach

发布时间 2023-07-17 09:40:22作者: NoAcalculia

线程启动、结束,创建线程多法、join,detach

视频链接:https://www.bilibili.com/video/BV1Yb411L7ak/?p=4&spm_id_from=333.880.my_history.page.click&vd_source=4c026d3f6b5fac18846e94bc649fd7d0
参考博主文章:https://blog.csdn.net/qq_38231713/article/details/106091372
img

join

示例代码

#include<iostream>
#include<thread>
using namespace std;
void test() {
	cout << "子线程开始" << endl;
	cout << "子线程结束" << endl;
}
int main() {
	 
	thread mythred(test);
	mythred.join();
	cout << "主线程结束" << endl;

}

结果示意图
img

代码解释

#include<thread>:导入线程库
thread mythred(test):创建进程这个类
mythred.join():join意思是汇合,阻塞主线程并等待myPrint执行完,当test执行完毕,join()就执行完毕,主线程继续往下执行
img
这样加断点可以知道可以知道mythred(test)一发生就test也开始了运行,但因为有join的出现所以必须等test执行完毕才行

因此一个(传统)良好的程序,必须是主线程等待所有子线程做完以后才能退出
下面就会打破这句话

detach()

可以实现分离,你走你的阳关道,我过我的独木桥
detach:分离,主线程不再与子线程汇合,不再等待子线程
detach后,子线程和主线程失去关联,驻留在后台,由C++运行时库接管,并且当子线程执行完成后,由运行时库负责清理相关的资源

示例代码

#include<iostream>
#include<thread>
using namespace std;
void test() {
	cout << "子线程开始" << endl;
	cout << "子线程结束" << endl;
}
int main() {
	 
	thread mythred(test);
	mythred.detach();
	cout << "主线程结束" << endl;
	return 0;
}

结果展示
img

代码解释

首先解释一下为什么子线程没有输出,其实是有的,但是因为主线称结束的太快,子线程还没开始就结束了,所以只要给主线程再加一些代码,让他运行的久一点,那么子线程就能数出了
mythred.detach():分离,主线程不再与子线程汇合,不再等待子线程

提醒

一旦detach后,就不能在join了

joinable()

判断是否可以成功使用join()或者detach()
有点简单直接上代码

#include <iostream>
#include <thread>
using namespace std;

void myPrint()
{
	cout << "我的线程开始运行" << endl;
	cout << "我的线程运行完毕" << endl;
	return;
}

int main()
{

	thread myThread(myPrint);

	myThread.join();

	//(4)joinable()判断是否可以成功使用join()或者detach()
	//如果返回true,证明可以调用join()或者detach()
	//如果返回false,证明调用过join()或者detach(),join()和detach()都不能再调用了
	if (myThread.joinable())
	{
		cout << "可以调用可以调用join()或者detach()" << endl;
	}
	else
	{
		cout << "不能调用可以调用join()或者detach()" << endl;
	}
	
	cout << "Hello World!" << endl;
	return 0;
}

补充说明

class Ta
{
public:
	void operator()() //不能带参数
	{
		cout << "我的线程开始运行" << endl;
		//-------------
		//-------------
		cout << "我的线程运行完毕" << endl;
	}
};

//main函数里的:
	Ta ta;
	thread myThread(ta);
	myThread.join();

这里有一点要补充说明,thread myThread(ta)里面传进去的ta不是真正的ta,而是复制一个ta在传进去(如果这个类他有拷贝构造的话,那么你将会看到它调用了拷贝构造),也就避免了主线程结束回收了ta,从而影响子线程运行,这里也给一个忠告,既然想到了主线程会回收,那么子线程要注意&引用,因为可能这个值传进去子线程,而主线程结束把这个值回收了。

lambda表达式

Lambda表达式是一种匿名函数的简洁写法,也被称为函数字面量。它允许您在需要函数的地方定义一个函数,而不必显式地给函数起一个具体的名字。Lambda表达式通常用于函数式编程中,特别是在需要传递函数作为参数或在需要简洁地定义函数的地方。(可以多去了解一下)

#include<iostream>
#include<thread>
using namespace std;
int main() {
	auto lambdaThread = [] {
		cout << "子线程开始" << endl;
		cout << "子线程结束" << endl;
	};
	thread mythred(lambdaThread);
	mythred.join();
	cout << "主线程开始" << endl;


	return 0;
}