程序运行起来,生成一个进程,该程序所属的主线程开始运行。以下函数就是一个进程。
#include "pch.h" #include <iostream> int main() { std::cout << "Hello World!\n"; return 0; } 主线程从main()函数开始执行,我们自己创建的线程,也需要从一个函数开始运行(初函数),一旦这个函数运行完毕 ,就代表我们的线程执行完毕。整个进程是否执行完毕的标志是 :主线程是否执行完毕,若果是就代表整个进程执行完毕。此时,一般情况下,若果其他子线程还没有执行完毕,那么这些子线程也会被操作系统强行终止。所以,一般情况下,如果想保持子线程(自己创建的线程)的运行状态的话,一定要保持主线程运行,不要其运行完毕(有例外,以后解释见detach())。thread标准库里的类,myprint可调用对象,创建子线程,线程执行起点,线程开始执行。
加入/汇合,术语阻塞,阻塞主线程,让主线程等待子线程执行完毕,然后子线程与主线程汇合,join执行完毕,主线程继续执行
包含一个头文件t#include < thread >;初始函数;main()中写代码;如下: #include "pch.h" #include <iostream> #include<thread> void myprint() { std::cout << "子线程开始执行。" << std::endl; //.... //.... std::cout << "子线程执行完毕。" << std::endl; } int main() { std::thread mytobj(myprint);//thread标准库里的类,myprint可调用对象,创建子线程,线程执行起点,线程开始执行。 mytobj.join(); //join()加入/汇合,术语阻塞,阻塞主线程,让主线程等待子线程执行完毕,然后子线程与主线程汇合,join执行完毕,主线程继续执行 std::cout << "主线程安全退出!" << std::endl; return 0; }注意,此程序包含两个线程,即同事做两个任务,一个任务被阻止,另一个可以继续执行。join很重要,没有join程序报错,程序执行混乱;不能保证子线程在主线程之前结束。
a.传统多线程程序要等子线程执行完毕,然后自己在退出;detach():分离也就是主线程与子线程不汇合,各执行各的,不必等待; b.为什么引入:我们创建很多子线程,让主线程逐个等待子线程结束,这种编程不太好,所以引入detach()一旦detach()后,与主线程关联的thread对象就会失去关联,子线程驻留在后台运行,被c++运行时库接管-建议少用
#include "pch.h" #include <iostream> #include<thread> void myprint() { std::cout << "子线程开始执行。" << std::endl; // ... //.... std::cout << "子线程执行完毕1。" << std::endl; std::cout << "子线程执行完毕2。" << std::endl; std::cout << "子线程执行完毕3。" << std::endl; std::cout << "子线程执行完毕4。" << std::endl; std::cout << "子线程执行完毕5。" << std::endl; std::cout << "子线程执行完毕6。" << std::endl; std::cout << "子线程执行完毕7。" << std::endl; std::cout << "子线程执行完毕8。" << std::endl; std::cout << "子线程执行完毕9。" << std::endl; std::cout << "子线程执行完毕10。" << std::endl; } int main() { std::thread mytobj(myprint); mytobj.detach(); std::cout << "主线程执行完毕。" << std::endl; return 0; }两次运行结果不一致,detach()会导致子线程失去控制,建议少用。一旦detach()后,不能join(),程序会报错。
判断是否成功使用join()或detach(),成功返回false,否则返回else。
#include "pch.h" #include <iostream> #include<thread> void myprint() { std::cout << "子线程开始执行。" << std::endl; // ... //.... std::cout << "子线程执行完毕1。" << std::endl; std::cout << "子线程执行完毕2。" << std::endl; std::cout << "子线程执行完毕3。" << std::endl; std::cout << "子线程执行完毕4。" << std::endl; std::cout << "子线程执行完毕5。" << std::endl; std::cout << "子线程执行完毕6。" << std::endl; std::cout << "子线程执行完毕7。" << std::endl; std::cout << "子线程执行完毕8。" << std::endl; std::cout << "子线程执行完毕9。" << std::endl; std::cout << "子线程执行完毕10。" << std::endl; } int main() { std::thread mytobj(myprint); if (mytobj.joinable()) { std::cout << "joinable()==true" << std::endl; } else { std::cout << "joinable()==false" << std::endl; } mytobj.detach(); if (mytobj.joinable()) { std::cout << "joinable()==true" << std::endl; } else { std::cout << "joinable()==false" << std::endl; } std::cout << "主线程执行完毕。" << std::endl; return 0; }疑问:一旦调用detach(),那主线程就结束了,这里用的ta对象还存在吗? 答:对象不存在,但是被复制到线程中去,执行完主线程后,ta被销毁,但所复制的对象依旧存在。所以,只要这个TA类对象里没有引用,没有指针,就不会产生问题。
