Linux--線程的控制與分離

一、線程的概念

    線程是進程內部的一個基本執行流,是系統調度的一個實體。進程具有獨佔性,線程具有共享性。各線程共享進程的文件描述符、信號處理的方式、當前的工作目錄、用戶id(uid)和組id(gid)。但是有些資源線程是私有的,比如線程id、棧空間、上下文(包括各種寄存器的值。程序計數器和棧指針)、佔空間、信號屏蔽字、調度優先級。就好比進程如果是一個家庭的話,線程就是這個家庭的成員,每個家庭的成員都有一個公共的空間(餐廳,客廳)。當然每個家庭成員也有自己的私人空間了。

二、線程的控制

   創建線程和終止

    用函數pthread_create()創建,成功返回0,失敗返歸錯誤號。調用 pthread_create()創建新的線程後。當前線程從pthread_create()返回繼續往下執行。新的線程所執行的代碼由函數指針start_routine決定。函數start_routine函數接收一個參數,是通過pthread_create()的arg傳給它的。類型爲void*,start_toutine的返回值類型也是void*,start_toutine返回後,這個線程就退出了,其他線程可以調用pthread_join()得到start_toutine的返回值。start_toutine函數可以通過①return(void*)、②pthread_exit(void*)、③pthread_cancel(pthread_self())三種終止。

  1 #include<stdio.h>
  2 #include<pthread.h>
  3 void * thread_run(void* arg)
  4 {
  5     int count=5;
  6     while(1)
  7     {
  8         printf("this is a thread,thread id is\n"pthread_self());
  9         sleep(1);
 10     }
 11     //return (void*)1;
 12     //pthread_exit((void*)2);
 13     // pthread_cancel(pthread_self());
 14 }
 15 int main()
 16 {
 17     pthread_t id;
 18     int ret=pthread_create(&id,NULL,thread_run,NULL);
 19     int count=10;
 20     while(count-->0)
 21     {
 22         printf("this is a main thread,thread id is %u\n",pthread_self());
 23         sleep(1);
 24     }
 25     void * ted=0;
 26     pthread_cancel(id);
 27     pthread_join(id,&ted);
 28     printf("return success %d\n",(int)ted);
 29 }

    wKioL1cTI5OyFxmNAANCmi8sCcI754.jpg可以看出:

    1、如果通過return返回。pthread_join接收的值是線程的返回值

    2、如果線程被別的線程調用pthread_cancel異常終止掉。則返回錯誤碼

    3、如果是調用pthread_exit終止的。pthread_join存放的是傳給pthread_exit的參數。

    4、兩個線程的線程號是不一樣的


三、線程分離

  線程在任一個時間點上。是可結合的(joinable)或者是可分離的(detached)。可結合的線程可被其他的線程回收資源和殺死。在被其他線程回收之前,它的存儲器資源是不釋放的。而可分離的線程是不能被其他回收或殺死的,它的存儲器資源在它終止時由系統自動釋放。默認情況下。線程被創建成可結合的。爲了避免內存泄漏,每個可結合的線程都應該要麼被顯示的回收,即調用pthread_join;要麼通過pthread_detach函數分離。

  如果如果一個可結合線程結束運行但沒有被pthread_join,則它的狀態類似於進程中的殭屍進程,即還有一部分資源沒有被回收,所以創建線程者應該調用pthread_join來等待線程運行結束,並可得到線程的退出代碼,回收其資源。調用pthread_join後,如果該線程沒有運行結束,調用者會被阻塞。這是可以在子線程中加入代碼pthread_detach(pthread_self())或者父線程調用pthread_detach(thread_id)非阻塞,可立即返回。這將該子線程的狀態設置爲分離的(detached),如此一來,該線程運行結束後會自動釋放所有資源。

  1 #include<stdio.h>
  2 #include<pthread.h>
  3 void* thread_run(void* arg)
  4 {
  5     pthread_detach(pthread_self()); //分離線程
  6     printf("this is a thrad \n");
  7     return (void*)1;
  8 }
  9 int main()
 10 {
 11     pthread_t id;
 12     int ret= pthread_create(&id,NULL,thread_run,NULL);
 13     printf("this is a main thread\n");
 14     sleep(1);
 15 
 16     int res=pthread_join(id,NULL);
 17     if(res==0)
 18     {
 19         printf("pthrad wait succced\n");
 20         return 0;
 21     }
 22     else
 23     {
 24         printf("pthread wait faile\n");
 25         return 1;
 26     }
 27     return 0;
 28 }

    wKiom1cTMeXjafr_AACavysWnN8526.jpg

如果把子線程中的pthread_detach(pthread_self())註釋掉,則結果如下,這是因爲把子線程中分離去掉後,其他線程就可以對子線程進程join和殺死,然後釋放掉存儲器資源。而上面是因爲在子進程中已經分離的,所以其他線程不能在對其訪問了,join返回fail

wKioL1cTMvzifinYAAClEkKL-NU838.jpg


總結:

    線程的控制從創建線程-->子線程的三種終止方式-->其他線程join線程。終止的方式不同,join的返回值就不同。線程的分離,如果子線程中加入pthread_detach()就把子線程設置成了可分離的線程,線程退出後會自動釋放存儲器資源,不會造成內存泄漏。如果不設置的話,就要用join顯示接收,然後釋放資源,也不會造成內存泄漏。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章