1、等待线程执行完成
join() 方法数会阻塞主线程直到目标线程调用完毕,即join会直接执行该子线程的函数体部分。
2、暂停线程(线程休眠)
使用std::this_thread::sleep_for或std::this_thread::sleep_until。
#include <thread> #include <iostream> #include <chrono> using namespace std::chrono; void pausable() { // sleep 500毫秒 std::this_thread::sleep_for(milliseconds(500)); // sleep 到指定时间点 std::this_thread::sleep_until(system_clock::now() + milliseconds(500)); } int main() { std::thread thread(pausable); thread.join(); return 0; }
3、线程终止
一般情况下当线程函数执行完成后,线程“自然”停止。但在std::thread中有一种情况会造成线程异常终止,那就是:析构。当std::thread实例析构时,如果线程还在运行,则线程会被强行终止掉,这可能会造成资源的泄漏,因此尽量在析构前join一下,以确保线程成功结束。
4、线程copy
std::thread a(foo);
std::thread b;
b = a;
将a的线程给了b,a不再管理该线程,如果b原来有线程,则原有线程被析构,管理新线程。
5、子线程分离
detach() 以后就失去了对线程的所有权,不能再调用join了,因为线程已经分离出去了,不再归该实例管了。判断线程是否还有对线程的所有权的一个简单方式是调用joinable函数,返回true则有,否则为无。
#include <thread> #include <iostream> using namespace std; // 一个普通的函数 void fun(int num) { cout << "The function child thread begin... "; cout << "I come from function fun(): " << num << ' '; cout << "The function child thread end... "; cout << endl; } // 一个函数类,实现了operator()方法 class Fun { public: void operator()(int num) { cout << "The class child thread begin... "; cout << "I come from class Fun: " << num << ' '; cout << "The class child thread end... "; cout << endl; } }; int main() { cout << "Main thread begin..." << ' '; cout.sync_with_stdio(true); // 设置输入流cout是线程安全的 thread t_1(fun, 1); // 新建线程,第一个参数是函数指针,第二个参数是函数的参数(第二个参数是可变长参数) t_1.join(); // join方法数会阻塞主线程直到目标线程调用完毕,即join会直接执行该子线程的函数体部分 thread t_2(fun, 2); t_2.detach(); // detach方法不会阻塞任何线程,目标线程就成为了守护线程,驻留后台运行 Fun oFun; thread t_3(ref(oFun), 3); //这里新建线程,使用对象进行初始化,这里的通过ref传递的是oFun本身而不是其拷贝 t_3.join(); cout << "Main thread end..." << endl; return 0; }