C++多线程join和detach

#include <Thread>

void func() {doSomthing();}

void main()

{

  std::Thread my_thread(func);

  my_thread.detach();

}

1、如上所示:通过Thread对象启动一个新线程时,如果调用detach()则当main()函数返回时,如果新的线程还没有返回则它将继续独自执行直到返回,这将引发一个问题,当新的线程访问main()中的局部变量时,由于main()已经结束,所以会出现访问被销毁的变量的错误,这种情况主要发生在访问指针或者引用变量时,避免此情况发生的一个方法是不要使用共享的变量,而是将局部变量拷贝到新的线程中去。另一个方法是使用join()。

2、如果将代码中的detach换乘join,则main()会等待新的线程返回,这种情况往往说明可以不使用多线程来完成任务,因为main()会发生空闲等待,造成浪费。当调用join()之后,my_thread将与任何线程无关,即使my_thread被销毁了,之前所关联的线程也不会调用std::terminate(),一个Thread对象只能调用一次join(),当调用一次join()后再调用joinable()将会返回FALSE。

3、调用detach或者join的时机,只需在my_thread被销毁之前调用即可。

4、在可能出现异常的情况下使用detach()和没有异常的情况下一样,但是使用join()却有不同,因为可能还没有调用join()就已经遇到异常而终止了程序,最好的方式是新建一个类,将my_thread传入类中,在类的析构函数中调用join(),调用前记得用joinable()判断是否可以join(),这样不论线程是异常退出还是正常退出,join都会起到作用。注意,在新建的类中,拷贝构造函数和拷贝赋值运算符都应该用=delete来禁止,因为拷贝一个Thread对象可能会使得它的生命周期超过它所绑定的线程。

5、当调用detach()后,my_thread也将与之前它所绑定的线程无关,调用joinable()也会返回FALSE,调用detach()使得线程在后台运行,这种情况适合于那些存在于整个生命周期的线程,比如:监测系统状态的线程等。在调用detach()之前也可以使用my_thread.joinable()来判断是否可以进行detach,joinable()返回TRUE时方可使用detach。

posted @ 2023-05-18 15:35  许卡文迪  阅读(163)  评论(0编辑  收藏  举报