C++多线程中的join, detach, joinable

回收子线程的资源有两种方法——join和detach:

  • join的意思是父线程等待子线程结束,在子线程结束时,负责回收子线程的资源。
  • detach的含义是父线程和子线程相互分离,即使父线程结束了,只要主线程没有结束,子线程就会继续正常运行。在子线程结束时,负责回收子线程的资源。
  • joinable()函数是一个布尔类型的函数,他会返回一个布尔值来表示当前的线程是否是可执行线程(能被join或者detach),因为相同的线程不能join两次,也不能join完再detach,同理也不能detach完再join,所以joinable函数就是用来判断当前这个线程是否可以joinable的。通常不能被joinable有以下几种情况:
    1)thread t;:t由缺省构造函数构建,此时线程未传入具体的线程函数。此时t.joinable()返回0,表示不可被join或者detach
    2)该thread被move过(包括move构造和move赋值)。【move指的是:线程的所有权将发生转移,原有线程对象的相关标识被清空,失去线程的控制权。其原有线程类对象ID变为0,joinable变为为false。(参考自:C++11中线程所有权转移分析)】
    3)该线程已经被join或者detach过。

参考:C++多线程中的join, detach, joinable

没有join和detach时

#include <iostream>
#include <thread>
#include <unistd.h>

using namespace std;
void func2(){
    cout<<"22222"<<endl;
}
 
void func(){
    cout<<"11111111"<<endl;
    thread t(func2);
    cout<<"33333333"<<endl;
}

int main(){
    func();
    cout<<"main"<<endl;

    sleep(10);

    return 0;
}

结果:

g++ -Wall -g -std=c++11 -pthread test2.cpp -o test2
./test2 
11111111
33333333
terminate called without an active exception
Aborted (core dumped)

在函数func中,启动线程t,但是线程t没有执行join或detach,那么在函数func执行完毕的时候就会发生错误,从而中断整个程序。

detach

detach的含义是父线程和子线程相互分离,即使父线程结束了,只要主线程没有结束,子线程就会继续正常运行。

#include <iostream>
#include <thread>
#include <unistd.h>

using namespace std;
void func(){

    sleep(1);
    cout<<"22222"<<endl;
}

void func2(){
    cout<<"11111111"<<endl;
    thread t(func);

    t.detach();
    cout<<"33333333"<<endl;
}

void func3(){
   sleep(10);
}

int main(){

     thread t2(func2);
     thread t3(func3);
     t3.join();
    cout<<"main"<<endl;

    return 0;
}

父线程t2创建子线程t,并使用detach分离父子线程。当t2结束时,因为此时主线程因为等待t3而未结束,所以t并不会结束。
虽说detach将父线程和子线程分离了,但是如果父线程时主线程的话,主线程结束子线程也会结束,此时子线程可能还有任务没有完成,比如:使用detach时,如果子线程还没清理垃圾,主线程就结束了,那么就会导致内存溢出

更多C++多线程,请参考此链接进行学习

posted @ 2022-07-27 21:21  好人~  阅读(1129)  评论(0编辑  收藏  举报