std::thread::join()的使用
线程启动后,若想等待该线程结束,可以调用join()方法;
std::thread thisThread(function_ptr); // 做一些其他的事情 th.join();
下面看个例子:
以下代码逻辑如下:
先启动10个线程,线程都开始运行;等待10个线程结束;所有线程join()完成后,主线程就会继续运行;
#include #include #include class WorkerThread {public: // 线程处理函数 void operator()() { std::cout << "Worker Thread " << std::this_thread::get_id() << " is Executing" << std::endl; }};int main() { // 创建10个线程 std::vector<:thread> threadList; for (int i = 0; i < 10; i++) { threadList.push_back(std::thread(WorkerThread())); } // 等待所有线程都结束 // 对于每个线程调用其join()函数 std::cout << "wait for all the worker thread to finish" << std::endl; std::for_each(threadList.begin(), threadList.end(), std::mem_fn(&std::thread::join)); std::cout << "Exiting from Main Thread" << std::endl; return 0;}
执行结果如下
调用join()函数执行结果
std::thread::detach()的使用
Detached线程常被用于守护/后台线程。调用线程的detach()方法可以detach一个线程。
std::thread thisThread(function_ptr); th.join();// 做一些其他的事情
调用detach()方法后,被detach的线程将不再关联执行线程;
下面看个例子
以下代码逻辑为:
先创建一个线程,该线程执行函数里循环打印3次内容;detach该线程;主线程循环打印15次内容;
#include #include #include class WorkerThread {public: void operator()() { for(int i = 0; i < 3; i++) { printf("Worker Thread is Executing, Index %d", i); } }};int main() { // 创建一个线程 auto detachThread = std::thread(WorkerThread()); // detach该线程 detachThread.detach(); // 继续主线程的一些事情,不受Worker线程影响 for(int i = 0; i < 20; i++) { printf("Main Thread is Executing, Index %d", i); } std::cout << "Main Thread Enter Wait Status." << std::endl; while(1) { std::this_thread::sleep_for(std::chrono::milliseconds(3 * 1000)); } return 0;}
结果如下:
detached的线程的执行结果
从上面可以看出:
detached的线程不阻塞当前执行;detach的线程在后台运行;
调用join()和detach()需要注意的地方
不要在没有关联执行线程的std::thread对象上调用join()和detach()函数一个关联了执行线程的std::thread对象,其可以调用join()/detach()函数,调用过以后,该std::thread对象将不再关联任何执行线程,再次调用,则会终止程序。
// 创建一个线程对象auto joinThread = std::thread(WorkerThread());// join该线程joinThread.join();// 此处如果再次join,会引起程序崩溃// joinThread.join();
如何防止该类种异常发生呢?
自己记着有没有调用过;调用std::thread的joinable()函数判断是否可以join/detach,如果返回true,则可以调用join()或detach()函数;
// 创建一个线程对象 auto joinThread = std::thread(WorkerThread()); // join该线程 joinThread.join(); // 此处如果再次join,会引起程序崩溃 // joinThread.join(); if(joinThread.joinable()) { joinThread.join(); }
不要忘记在关联了执行线程的std::thread对象上调用join()和detach()函数
如果一个std::thread对象既没有调用join(),也没有调用detach()的话,则当std::thread析构的时候会引发程序崩溃。
示例程序:
#include #include #include class WorkerThread {public: void operator()() { for(int i = 0; i < 3; i++) { printf("Worker Thread is Executing, Index %d", i); } }};int main() { // 创建一个线程对象 auto joinThread = std::thread(WorkerThread()); // 此处如果不join该线程, 线程退出,joinThread对象析构会导致程序崩溃 // joinThread.join(); printf("Exist Main Thread"); return 0;}
执行如下:
没有调用join/detach引发的异常
可用的解决方案:
可以用自定义类包裹,在自定义类析构函数中detach()线程对象,代码如下:
#include #include #include class ThreadWrap {public: ThreadWrap(std::thread& threadObj) : _thread(threadObj) {} ~ThreadWrap() { if (_thread.joinable()) { _thread.detach(); } }private: std::thread& _thread;};void thread_fun_cb() { for (int i = 0; i < 1000; i++) { printf("Thread function running, index %d", i); // 休眠10ms std::this_thread::sleep_for(std::chrono::milliseconds(10)); }}int main() { // 创建线程对象 std::thread testThread(thread_fun_cb); ThreadWrap wrapThread(testThread); // 此处休眠10ms,给子线程执行机会 std::this_thread::sleep_for(std::chrono::milliseconds(100)); printf("Exist Main Thread"); return 0;}
上述代码执行结果如下:
未调用join/detach导致崩溃解决方案结果
上诉执行结果可以看到,子线程还没结束,主线程退出了,但是没引起崩溃。
好了,到此吧,该干活了~~~
如果觉得《android 开启子线程执行for循环_C++11之多线程 - Part2 Joining和Detaching的使用》对你有帮助,请点赞、收藏,并留下你的观点哦!