分離式線程

一、技術都是爲了解決實際問題的,考慮下面的場景:
    主線程建立一個子線程,子線程作一些任務,在主線程上,等待子線程完成任務,而後向下運行。代碼以下:
    #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以後,分離式線程剛開始執行。
相關文章
相關標籤/搜索