目录
1--基于 thread 创建线程
使用 C++ 的 thread 标准库可以创建线程:常用的 API 有 join()、detach() 和 joinable() 等;
join() 一般用于阻塞主线程,使得主线程需要等待子线程执行完毕才结束;
detach() 用于分离子线程与主线程,主线程无需等待子线程执行完毕才结束,当主线程结束后,子线程转由后台运行;
joinable() 用于判断是否可以使用 join() 或 detach(),能使用返回 true,不能使用返回 false(),当一个子线程调用 detach() 后不能再调用 join();
注:在 linux 环境下编译时加上 -lpthread 参数(cmake 加上 target_link_libraries(main pthread))
1-1--使用函数对象创建线程
# include <iostream>
# include <thread>
void myprint(){
int i = 100;
while(i > 0){
std::cout << "thread print" << std::endl;
i--;
}
}
int main(){
// 创建子线程对象
std::thread thread1(myprint);
int i = 100;
while(i > 0){
std::cout << "main print" << std::endl;
i--;
}
thread1.join(); // 阻塞主线程,主线程需等待子线程执行完毕
return 0;
}
1-2--使用类对象创建线程
# include <iostream>
# include <thread>
class myclass{
public:
// 函数名必须为 operator, 且不能携带参数
void operator()(){
int i = 100;
while(i > 0){
std::cout << "thread print" << std::endl;
i--;
}
}
};
int main(){
// 创建子线程对象
myclass class1;
std::thread thread1(class1);
int i = 100;
while(i > 0){
std::cout << "main print" << std::endl;
i--;
}
thread1.join(); // 阻塞主线程,主线程需等待子线程执行完毕
return 0;
}
当使用 detach() 时,应避免由于主线程执行完毕,导致主线程的所有变量被回收,从而引用传递给子线程的变量变成未知变量的错误,例如以下代码的情况:
主线程创建子线程时,传入 index 的引用传递,当使用 detach() 分离主线程和子线程时,若主线程首先结束将会回收 index 变量,这时引用传递给类对象的 index 将变为未知,从而引起 error 和 bug 等;
因此,当使用 detach() 应尽量避免引用传递,可以改用普通传递,将主线程的对象或变量重新赋值拷贝一份到子线程中;
// Error bug code
# include <iostream>
# include <thread>
class myclass{
public:
myclass(int &index):my_i(index){}; // 用引用传递的 i 初始化 my_i
// 函数名必须为 operator, 且不能携带参数
void operator()(){
int i = 100;
while(i > 0){
std::cout << "thread print" << std::endl;
i--;
}
}
private:
int my_i;
};
int main(){
// 创建子线程对象
int index = 1;
myclass class1(index);
std::thread thread1(class1);
int i = 100;
while(i > 0){
std::cout << "main print" << std::endl;
i--;
}
thread1.detach(); // 阻塞主线程,主线程需等待子线程执行完毕
return 0;
}
1-3--使用lambda表达式创建线程
# include <iostream>
# include <thread>
int main(){
auto lamthread = [](){
int i = 100;
while(i > 0){
std::cout << "thread print" << std::endl;
i--;
}
};
std::thread thread1(lamthread);
thread1.detach(); // 主线程和子线程分离
int j = 100;
while(j > 0){
std::cout << "main print" << std::endl;
j--;
}
return 0;
}