Linux线程的创建与回收
Linux中的線程的創建與回收
- 線程創建
- pthread_creat函數
- 線程回收
- pthread_join函數 && pthread_detach函數
- 參考博客
線程創建
1.為什么引入線程
- 進程在切換時系統開銷大
- 很多做操作系統引入了輕量級進程(LWP)
- 同一線程共享相同的地址空間
- Linux本質上不區分進程、線程
2. 進程與線程的區別
-
進程是計算機中的程序關于某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。這里主要強調獨立進程有獨立的地址空間,Linux為每個進程創建task_struct。每個進程都參與內核調度,互不影響。
-
線程是進程的一個實體, 是CPU調度和分派的基本單位,它是比進程更小的能獨立運行的基本單位.線程自己基本上不擁有系統資源,只擁有一點在運行中必不可少的資源(如程序計數器,一組寄存器和棧,下面會細說),但是它可與同屬一個進程的其他的線程共享進程所擁有的全部資源。
-
一個線程可以創建和撤銷另一個線程,同一個進程中的多個線程之間可以并發執行。
3. 使用線程的好處
- 大大提高了任務切換的效率
- 避免了額外的TLB&cache的刷新
pthread_creat函數
#include <pthread.h> int pthread_create(pthread_t *tidp,const pthread_attr_t *attr, void *(*start_rtn)(void*),void *arg); /*C99中將第一個參數限定為restrict restrict 限定符,表明指針是訪問一個數據對象的唯一且初始的方式.即它告訴編譯器,所有修改該指針所指向內存中內容的操作都必須通過該指針來修改,而不能通過其它途徑(其它變量或指針)來修改;這樣做的好處是,能幫助編譯器進行更好的優化代碼,生成更有效率的匯編代碼. */- 成功時返回0,失敗時返回錯誤碼
- 第一個參數 : thread 線程對象
- 第二個參數 : 線程屬性,NULL代表默認屬性
- 第三個參數 :線程執行的函數
- 第四個參數 :執行函數的參數
這里著重說一下第二個參數,我們可以看到第二個參數的類型是pthread_attr_t指針類型下面具體說一下
typedef struct {int detachstate; //線程的分離狀態int schedpolicy; // 線程調度策略structsched_param schedparam; //線程的調度參數int inheritsched; //線程的繼承性int scope; //線程的作用域size_t guardsize; //線程棧末尾的警戒緩沖區大小int stackaddr_set;void* stackaddr; //線程棧的位置size_t stacksize; //線程棧的大小 }pthread_attr_t;- __detachstate —— 表示新線程是否與進程中其他線程脫離同步,如果置位則新線程不能用pthread_join()來同步與回收,且在退出時自行釋放所占用的資源。缺省為 PTHREAD_CREATE_JOINABLE狀態。這個屬性也可以在線程創建并運行以后用pthread_detach()來設置,而一旦設置為 PTHREAD_CREATE_DETACH狀態(不論是創建時設置還是運行時設置)則不能再恢復到 PTHREAD_CREATE_JOINABLE狀態。這個屬性與線程回收相關,下面會細講兩種狀態的區別。
- __schedpolicy——表示新線程的調度策略,主要包括 SCHED_OTHER(正常、非實時)、SCHED_RR(實時、輪轉法)和 SCHED_FIFO(實時、先入先出)三種,缺省為SCHED_OTHER,后兩種調度策略僅對超級用戶有效。運行時可以用過 pthread_setschedparam()來改變。
- __schedparam——一個struct sched_param結構,目前僅有一個sched_priority整型變量表示線程的運行優先級。這個參數僅當調度策略為實時(即SCHED_RR 或SCHED_FIFO)時才有效,并可以在運行時通過pthread_setschedparam()函數來改變,缺省為0。
- __inheritsched——有兩種值可供選擇:PTHREAD_EXPLICIT_SCHED和PTHREAD_INHERIT_SCHED,前者表示新線程使用顯式指定調度策略和 調度參數(即attr中的值),而后者表示繼承調用者線程的值。缺省為PTHREAD_EXPLICIT_SCHED。
- __scope——表示線程間競爭CPU的范圍,也就是說線程優先級的有效范圍。POSIX的標準中定義了兩個值: PTHREAD_SCOPE_SYSTEM和PTHREAD_SCOPE_PROCESS,前者表示與系統中所有線程一起競爭CPU時間,后者表示僅與同 進程中的線程競爭CPU。目前LinuxThreads僅實現了PTHREAD_SCOPE_SYSTEM一值。
- __stacksize——表示線程棧的大小,若不指定則默認為ulimit 中的 stack大小。一般來說是8388608字節。如果是嵌入式開發的話,一般需要通過pthread_attr_setstacksize重新設置值。否則可能創建失敗返回12錯誤碼(ENOMEM ).。
pthread_attr_t結構中還有一些值,但不使用pthread_create()來設置。
線程回收
pthread_join函數 && pthread_detach函數
int pthread_join(pthread_t thread, void **retval);int pthread_join(pthread_t thread, void **retval);這里線程的回收與進程的類似。一個線程對應一個pthread_join()調用,對同一個線程進行多次pthread_join()調用是邏輯錯誤。join函數只能回收 PTHREAD_CREATE_JOINABLE狀態的線程。其他狀態不可以。當線程處于PTHREAD_CREATE_JOINABLE狀態時,如果線程結束運行還沒有被回收,則它的 狀態類似于進程中的Zombie Process(僵尸進程),還有一部分的資源沒有被系統回收(退出狀態碼),所以要調用pthread_join函數等待要結束的線程,并可以的到線程退出的狀態碼。
那么上述就可以發生線程沒執行完,就執行到join函數,調用者會被阻塞,直到線程執行完成并且回收。但是有時候我們不希望因線程未執行完而被阻塞。比如在Web服務器中當主線程為每個新來的鏈接創建一個子線程進行處理的時候,主線程并不希望因為調用pthread_join而阻塞(因為還要繼續處理之后到來的鏈接),這時可以在子線程中加入代碼
或者父線程調用
pthread_detach(thread_id)//(非阻塞,可立即返回)這將該子線程的狀態設置為detached,則該線程運行結束后會自動釋放所有資源。
最后關注我,點個贊再走吧(?>?<?)
參考博客
[1] https://blog.csdn.net/tongxinhaonan/article/details/42558561
[2] http://zhaojunjie.blog.51cto.com/5475365/1033968
[3] https://baike.baidu.com/item/pthread_detach
總結
以上是生活随笔為你收集整理的Linux线程的创建与回收的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FLUENT 流体计算应用教程
- 下一篇: Linux线程详解(概念、原理、实现方法