主线程从 main() 函数开始执行,子线程也需要从一个函数开始运行(初始函数),一旦此函数运行完毕,该线程就结束了。
1 进程结束的标志
主线程执行完毕(子线程不论是否结束都会被终止,有例外情况)
2 创建线程
#include <iostream>
#include <thread>
using namespace std;
void SubThreadPrint() {
cout << "子线程开始运行" << endl;
cout << "子线程运行完毕" << endl;
return;
}
int main() {
// 创建线程
// 执行线程
thread my_thread(SubThreadPrint);
// 阻塞主线程
// 子线程执行完,主线程继续往下执行
my_thread.join();
// 主线程不再等待子线程
// 子线程与主线程失去关联,驻留在后台,由C++运行时库接管
// my_thread.detach();
// 判断是否可以成功使用 join() 或者 detach()
//如果返回 true,证明可以调用 join() 或者 detach()
//如果返回 false,证明调用过 join() 或者 detach(),join() 和 detach() 都不能再调用了
if (my_thread.joinable()) {
cout << "可以调用可以调用join()或者detach()" << endl;
} else {
cout << "不能调用可以调用join()或者detach()" << endl;
}
cout << "Hello World!" << endl;
return 0;
}
3 其他创建线程的方法
理论依据:
线程类参数是一个可调用对象。
一组可执行的语句称为可调用对象,C++中的可调用对象可以是函数、函数指针、lambda表达式、bind创建的对象或者重载了函数调用运算符的类对象。
3.1 创建类,重载函数调用运算符,初始化该类的对象,把该对象作为线程入口地址
#include <iostream>
#include <thread>
using namespace std;
class SubThreadClass {
public:
// 不能带参数
void operator()() {
cout << "子线程开始运行" << endl;
cout << "子线程运行完毕" << endl;
}
};
int main() {
SubThreadClass sub_thread_class;
// 创建线程
// 执行线程
thread my_thread(sub_thread_class);
// 阻塞主线程
// 子线程执行完,主线程继续往下执行
my_thread.join();
// 主线程不再等待子线程
// 子线程与主线程失去关联,驻留在后台,由C++运行时库接管
// my_thread.detach();
// 判断是否可以成功使用 join() 或者 detach()
//如果返回 true,证明可以调用 join() 或者 detach()
//如果返回 false,证明调用过 join() 或者 detach(),join() 和 detach() 都不能再调用了
if (my_thread.joinable()) {
cout << "可以调用可以调用join()或者detach()" << endl;
}
else {
cout << "不能调用可以调用join()或者detach()" << endl;
}
cout << "Hello World!" << endl;
return 0;
}
3.2 lambda 表达式创建线程
#include <iostream>
#include <thread>
using namespace std;
int main() {
auto lambda_thread = [] {
cout << "子线程开始执行了" << endl;
cout << "子线程开始执行了" << endl;
};
// 创建线程
// 执行线程
thread my_thread(lambda_thread);
// 阻塞主线程
// 子线程执行完,主线程继续往下执行
my_thread.join();
// 主线程不再等待子线程
// 子线程与主线程失去关联,驻留在后台,由C++运行时库接管
// my_thread.detach();
// 判断是否可以成功使用 join() 或者 detach()
//如果返回 true,证明可以调用 join() 或者 detach()
//如果返回 false,证明调用过 join() 或者 detach(),join() 和 detach() 都不能再调用了
if (my_thread.joinable()) {
cout << "可以调用可以调用join()或者detach()" << endl;
}
else {
cout << "不能调用可以调用join()或者detach()" << endl;
}
cout << "Hello World!" << endl;
return 0;
}
3.3 把某个类中的某个函数作为线程的入口地址
#include <iostream>
#include <thread>
using namespace std;
class Data_ {
public:
void GetMsg() {
cout << "GetMsg 子线程开始执行了" << endl;
cout << "GetMsg 子线程开始执行了" << endl;
}
void SaveMsg() {
cout << "SaveMsg 子线程开始执行了" << endl;
cout << "SaveMsg 子线程开始执行了" << endl;
}
};
int main() {
Data_ data;
// 第一个 & 是取址
// 第二个 & 是引用
thread my_thread1(&Data_::GetMsg, &data);
thread my_thread2(&Data_::SaveMsg, &data);
my_thread1.join();
my_thread2.join();
cout << "Hello World!" << endl;
return 0;
}
运行结果如下
SaveMsg 子线程开始执行了
SaveMsg 子线程开始执行了
GetMsg 子线程开始执行了
GetMsg 子线程开始执行了
Hello World!
C:\Users\null\source\repos\Project1\Debug\Project1.exe (进程 14644)已退出,代码为 0。
要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口. . .