一篇帶你完全掌握線程的博客


  前言:最近一直在瘋狂學習,之前也不太了解線程,現在基本都掌握了。如果你之前也不知道線程,也不知道進程和線程的區別等等,這一篇博客帶你完全掌握,不掌握不要錢,哈哈哈!

  一、線程概念

   介紹概念之前,先畫個圖吧,依舊是全博客園最丑圖,不接受反駁!

  

  

  簡單說明一下:進程在其內部創建線程,線程有自己的PCB,但沒有獨立的地址空間。

  線程和進程具有以下特征和區別:

  LWP:light weight process 輕量級的進程,本質仍是進程(在Linux環境下)

  進程:獨立地址空間,擁有PCB

        線程:也有PCB,但沒有獨立的地址空間(共享)

        區別:在於是否共享地址空間。         獨居(進程);合租(線程)。

        Linux下:          線程:最小的執行單位(CPU分配時間輪片是通過線程來實現的)

                                    進程:最小分配資源單位,可看成是只有一個線程的進程

  參考:《Linux內核源代碼情景分析》 ----毛德操

  二、線程共享資源  

    1.文件描述符表

         2.每種信號的處理方式

         3.當前工作目錄

         4.用戶ID和組ID

         5.內存地址空間 (.text/.data/.bss/heap/共享庫)

  三、線程非共享資源

   1.線程id

         2.處理器現場和棧指針(內核棧)

         3.獨立的棧空間(用戶空間棧)

         4.errno變量

         5.信號屏蔽字

         6.調度優先級

  四、線程的優缺點

    優點:     1. 提高程序並發性        2. 開銷小        3. 數據通信、共享數據方便

         缺點:     1. 庫函數,不穩定        2. 調試、編寫困難、gdb不支持          3. 對信號支持不好

         優點相對突出,缺點均不是硬傷。Linux下由於實現方法導致進程、線程差別不是很大。

  五、線程相關函數

  在學習線程函數之前,再說點題外話。類Unix系統中,早期是沒有“線程”概念的,80年代才引入,借助進程機制實現出了線程的概念。因此在這類系統中,進程和線程關系密切。所以可以將線程相關函數與進程函數進行對比學習。

  •   pthread_self函數

  功能:獲取線程ID。其作用對應進程中 getpid() 函數。

  原型:pthread_t pthread_self(void);

  返回值:成功:0;       失敗:無!

  線程ID:pthread_t類型,本質:在Linux下為無符號整數(%lu),其他系統中可能是結構體實現

       線程ID是進程內部,識別標志。(兩個進程間,線程ID允許相同)  

  •   pthread_create函數 

   功能:創建一個新線程。                   其作用,對應進程中fork() 函數。

  原型:int pthread_create(pthread_t *thread, const pthread_attr_t *attr,void *(*start_routine) (void *), void *arg);

  返回值:成功:0;       失敗:錯誤號         -----Linux環境下,所有線程特點,失敗均直接返回錯誤號。

  參數說明:

  pthread_t:當前Linux中可理解為:typedef  unsigned long int  pthread_t;

  參數1:傳出參數,保存系統為我們分配好的線程ID

       參數2:通常傳NULL,表示使用線程默認屬性。若想使用具體屬性也可以修改該參數。

       參數3:函數指針,指向線程主函數(線程體),該函數運行結束,則線程結束。

       參數4:線程主函數執行期間所使用的參數。跟參數三關聯。

  注意:鏈接線程庫 -lpthread

  寫一個簡單程序,演示這兩個函數用法:

  

#include<stdio.h>
#include<unistd.h>
#include<pthread.h>

void *tfn(void *arg)
{
    printf("child thread%lu\n",pthread_self());
    return NULL;
}

int main()
{
    pthread_t tid;
    pthread_create(&tid,NULL,tfn,NULL);
    sleep(1);
    printf("main thread:%lu\n",pthread_self());
    
    return 0;
}
View Code

  編譯:gcc pthread_cre.c -lpthread,記得鏈接線程庫 -lpthread

  •    pthread_exit函數

  功能:將單個線程退出 相當於exit

  原型:void pthread_exit(void *retval);

  參數:retval表示線程退出狀態,通常傳NULL

  •   pthread_join函數

  功能:阻塞等待線程退出,獲取線程退出狀態              其作用,對應進程中 wait()、waitpid() 函數。

  原型:int pthread_join(pthread_t thread, void **retval);

  參數:thread:線程ID (【注意】:不是指針);retval:存儲線程結束狀態。

  •   pthread_detach函數

  功能:實現線程分離 線程獨有的,沒有進程的相關函數與之對應

  原型:int pthread_detach(pthread_t thread);

  線程分離狀態:指定該狀態,線程主動與主控線程斷開關系。線程結束后,其退出狀態不由其他線程獲取,而直接自己自動釋放。網絡、多線程服務器常用。

  重點:分離狀態的線程就不需要回收了!!!重要的事情說三遍,三遍,三遍!!!

  •   pthread_cancel函數

  功能:殺死(取消)線程                         其作用,對應進程中 kill() 函數。

  原型:int pthread_cancel(pthread_t thread);

  【注意】:線程的取消並不是實時的,而有一定的延時。需要等待線程到達某個取消點(檢查點)。

   六、控制原語對比

  就是就是將進程相關函數與線程函數,進行對比來記憶:

  進程                        線程

     fork                     pthread_create

     exit                     pthread_exit

     wait                    pthread_join

     kill                       pthread_cancel

     getpid                pthread_self              

  總結:歡迎評論,交流與學習。

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM