前言:最近一直在瘋狂學習,之前也不太了解線程,現在基本都掌握了。如果你之前也不知道線程,也不知道進程和線程的區別等等,這一篇博客帶你完全掌握,不掌握不要錢,哈哈哈!
一、線程概念
介紹概念之前,先畫個圖吧,依舊是全博客園最丑圖,不接受反駁!
簡單說明一下:進程在其內部創建線程,線程有自己的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; }
編譯: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
總結:歡迎評論,交流與學習。