失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > android 开启子线程执行for循环_C++11之多线程 - Part2 Joining和Detaching的使用

android 开启子线程执行for循环_C++11之多线程 - Part2 Joining和Detaching的使用

时间:2022-09-17 16:00:42

相关推荐

android 开启子线程执行for循环_C++11之多线程 - Part2 Joining和Detaching的使用

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的使用》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。