分离式线程

一、技术都是为了解决实际问题的,考虑下面的场景:
    主线程建立一个子线程,子线程作一些任务,在主线程上,等待子线程完成任务,而后向下运行。代码以下:
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    
    void* FuncA(void* arg)
    {
        printf("FuncA Time[%d]\n", time(NULL));
        sleep(2);
    }
    
    int main(int argc,char* argv[])
    {
        pthread_t threadA;
        pthread_create(&threadA, NULL, FuncA, NULL);
    
        pthread_join(threadA,NULL);
        printf("main  Time[%d]\n", time(NULL));
        getchar();
        return 0;
    }
    
    [niu_zibin@localhost thread]$ g++ -o main main.cpp -lpthread
    [niu_zibin@localhost thread]$ ./main
    FuncA Time[1477297071]
    main  Time[1477297073]
二、能够看到,主线程阻塞在pthread_join,那么问题来了,如何让主线程不阻塞在pthread_join呢?
三、上面产生的缘由是:默认建立的线程A不是分离的,也就是被主线程关联。
    所以,解决办法是:建立线程A的时候,把它设置成分离的,再也不被别的线程关联。以下:
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    
    void* FuncA(void* arg)
    {
        printf("First  FuncA Time[%d]\n", time(NULL));
        sleep(2);
        printf("Second FuncA Time[%d]\n", time(NULL));
    }
    
    int main(int argc,char* argv[])
    {
        pthread_t threadA;
        pthread_attr_t pAttr;
        pthread_attr_init(&pAttr);
        pthread_attr_setdetachstate(&pAttr,PTHREAD_CREATE_DETACHED);
        pthread_create(&threadA, &pAttr, FuncA, NULL);
    
        int ret = pthread_join(threadA,NULL);
        printf("pthread_join ret[%d]\n",ret);
        printf("main  Time[%d]\n", time(NULL));
        getchar();
        return 0;
    }
    
    [niu_zibin@localhost thread]$ g++ -o main main.cpp -lpthread
    [niu_zibin@localhost thread]$ ./main
    pthread_join ret[22]
    main  Time[1477298407]
    First  FuncA Time[1477298407]
    Second FuncA Time[1477298409]
    再也不阻塞。
四、注意:设置了分离状态【PTHREAD_CREATE_DETACHED】,pthread_join返回错误。
    改为可结合状态【PTHREAD_CREATE_JOINABLE】,pthread_join返回成功,以下:
    pthread_attr_setdetachstate(&pAttr,PTHREAD_CREATE_JOINABLE);
    
    [niu_zibin@localhost thread]$ g++ -o main main.cpp -lpthread
    [niu_zibin@localhost thread]$ ./main 
    First  FuncA Time[1477298637]
    Second FuncA Time[1477298639]
    pthread_join ret[0]
    main  Time[1477298639]
五、还有一种办法,就是建立线程A以后,也就是在线程A运行的时候,进行分离操做,以下:
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    
    void* FuncA(void* arg)
    {
        printf("First  FuncA Time[%d]\n", time(NULL));
        sleep(2);
        printf("Second FuncA Time[%d]\n", time(NULL));
    }
    
    int main(int argc,char* argv[])
    {
        pthread_t threadA;
        pthread_create(&threadA, NULL, FuncA, NULL);
    
        pthread_detach(threadA);
        pthread_join(threadA,NULL);
        printf("main  Time[%d]\n", time(NULL));
        getchar();
        return 0;
    }
    
    [niu_zibin@localhost thread]$ g++ -o main main.cpp -lpthread
    [niu_zibin@localhost thread]$ ./main
    main  Time[1477298924]
    First  FuncA Time[1477298924]
    Second FuncA Time[1477298926]
六、线程是可结合(joinable)或者分离的(detached)。
    对于可结合线程A,被主线程回收资源(好比A的线程栈)和杀死,在主线程join线程A以前,线程A的资源是不会被释放的。
    对于分离式线程A,在它终止后,系统会自动释放线程A的资源。
七、对于分离式线程A,考虑一种极端的状况,分离式线程执行特别快,在pthread_create返回以前就已经终止了。
    这就意味着,pthread_create返回的数据是垃圾数据。
八、怎么解决上面的问题?
    在分离式线程A中执行pthread_cond_timewait函数,让当前线程等待一会,确保pthread_create返回的时候,当前线程尚未终止。
    还有一种办法,使用PV操做,分离式线程内先执行P操做,卡在这里。在主线程pthread_create以后进行V操做,
    从而确保pthread_create以后,分离式线程刚开始执行。
相关文章
相关标签/搜索