线程启动、结束,创建线程多法、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
join
示例代码
#include<iostream>
#include<thread>
using namespace std;
void test() {
cout << "子线程开始" << endl;
cout << "子线程结束" << endl;
}
int main() {
thread mythred(test);
mythred.join();
cout << "主线程结束" << endl;
}
结果示意图
代码解释
#include<thread>
:导入线程库
thread mythred(test)
:创建进程这个类
mythred.join()
:join意思是汇合,阻塞主线程并等待myPrint执行完,当test执行完毕,join()就执行完毕,主线程继续往下执行
这样加断点可以知道可以知道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;
}
结果展示
代码解释
首先解释一下为什么子线程没有输出,其实是有的,但是因为主线称结束的太快,子线程还没开始就结束了,所以只要给主线程再加一些代码,让他运行的久一点,那么子线程就能数出了
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;
}