Linux之執行緒小議

2021-09-22 13:59:42 字數 3364 閱讀 8496

說到執行緒概念,必須先說明程序。程序是乙個執行中的程式,在作業系統中,乙個程式執行起來後就會被載入到記憶體中。作業系統建立了乙個程序描述符(pcb)對程式的執行進行描述控制。因此程序就是pcb,在linux下用task_struct結構體來描述。linux系統下,用程序pcb來模擬線程,因此linux下乙個執行緒就是乙個輕量級程序。如果說pcb稱為了執行緒,那麼程序就是執行緒組。乙個程序中至少有乙個或多個執行緒。

因為linux下pcb是乙個執行緒,因此執行緒是cpu排程的基本單位。因為程式執行時候分配資源,程序(執行緒組)是資源分配的基本單位。程序中的所有執行緒共用乙個虛擬位址空間,因此可以共享程序的**段和資料段又因為執行緒之間資料的共享,所以執行緒之間進行通訊就變得極為簡單

因為每個執行緒都是pcb,是cpu排程的基本單位,因此執行緒可以同時執行,但不會造成呼叫棧混亂,主要是因為每個執行緒都有自己的獨有資料

棧上下文資料

訊號遮蔽字

errno

執行緒識別符號

既然多程序可以並行處理任務,多執行緒也可以。其優缺點分析如下(根據具體使用情況):

多執行緒的優點:因為執行緒共享虛擬位址空間,執行緒間通訊簡單,執行緒的建立/銷毀成本更低,執行緒的執行粒度更細。

多執行緒缺點:執行緒缺乏訪問控制(可以訪問虛擬位址空間中的任何一塊資料);但執行緒的某些錯誤會導致整個程序退出,即健壯性較低。

注意:執行緒的數量也並非越多越好,因為過多的話會導致切換頻繁,在一定程度上反而會降低效能。

作業系統並沒有提供直接的建立執行緒的介面(使用者建立執行緒很麻煩),因此前輩們實現了一套執行緒控制介面供使用者使用。因此我們說建立的執行緒是乙個使用者態的執行緒,但是在核心對應有乙個輕量級程序實現程式的排程執行。

2.1 執行緒建立

int

pthread_create

(pthread_t *thread, pthread_addr_t *arr,

void*(

*start_routine)

(void*)

,void

*arg)

;//thread    :用於返回建立的執行緒的id

//arr       : 用於指定的被建立的執行緒的屬性,上面的函式中使用null,表示使用預設的屬性

//start_routine : 這是乙個函式指標,指向執行緒被建立後要呼叫的函式

//arg      : 用於給執行緒傳遞引數,在本例中沒有傳遞引數,所以使用了null

2.2 執行緒終止

如果需要只終止某個執行緒而不終止整個程序,可以有以下三種方法:

從執行緒函式return。這種方法對主線程不適用,從main函式return相當呼叫exit.

(在main中return,退出整個程序;在普通入口函式中return,只是退出呼叫執行緒)

執行緒可以呼叫pthread_exit來終止自己(退出呼叫執行緒)

pthread_cancel用來取消指定執行緒,也可以取消自己。

pthread_exit()函式

//功能:執行緒終止

//原型:

void

pthread_exit

(void

* value_ptr)

;//引數:

value_ptr:不能指向乙個區域性變數

//返回值:無。跟程序一樣,執行緒結束的時候無法返回到它的呼叫者。

pthread_cancel()函式

//功能:取消乙個執行中的執行緒

//原型:

intpthread_cancel

(pthread_t thread)

;//引數:

thread: 執行緒id

//返回值:成功返回0,失敗返回錯誤碼

2.3 執行緒等待

為什麼要進行執行緒等待呢?簡言之,執行緒退出後可能會產生「殭屍執行緒」,所以要等待,以免造成資源洩露。換句話說,即:

等待指定執行緒退出,就是要獲取指定執行緒的返回值,**執行緒資源。因為乙個執行緒被建立後,預設有乙個屬性為joinable,處於這個屬性的執行緒必須被等待,因為執行緒退出後,不會自動地**資源,會造成資源洩露

pthread_join()

//功能:等待執行緒結束

//原型:

intpthread_join

(pthread_t thread,

void

** value_ptr)

;//引數:

thread:執行緒id

value_ptr:指向乙個指向被連線線程的返回碼的指標的指標

//返回值:成功返回0, 失敗返回錯誤碼。

呼叫該函式的執行緒將掛起等待,直到id為thread的執行緒終止。thread執行緒以不同的方法終止,通過pthread_join得到的終止狀態是不同的,總結如下:

如果thread執行緒通過return返回,value_ptr所指向的單元裡存放的是thread執行緒函式的返回值。

如果thread執行緒被別的執行緒呼叫pthread_cancel異常終止掉,value_ptr所指向的單元裡存放的是常熟pthread_canceled。

如果thread執行緒是自己呼叫pthread_exit()終止的,value_ptr所指向的單元存放的是傳給pthread_exit()的引數。

如果對thread執行緒的終止狀態不感興趣,可以傳null給value_ptr引數。

2.4 執行緒分離

為什麼要進行執行緒分離呢?(通俗點來說,「對誰不關心,就去分離誰,不去等待誰」)。 即:

分離乙個執行緒,將執行緒的joinable屬性修改為detach屬性,處於此屬性的執行緒,退出後將自動**資源。此屬性的執行緒,不能被等待,否則就會報錯。

預設情況下,新建立的執行緒是joinable的,執行緒退出後,需要對其進行pthread_join操作,否則無法釋放資源,從而造成資源洩露;

如果不關心執行緒的返回值,join是一種負擔,這個時候,我們可以告訴系統,當執行緒退出時,自動釋放執行緒資源。

//執行緒組內其他執行緒對目標執行緒進行分離

intpthread_detach

(pthread_t thread)

;//也可以是執行緒自己分離自己

intpthread_detach

(pthread_self()

);//pthread_self()函式獲得執行緒自身的id

執行緒 程序的區別之小議 二

關於多程序和多執行緒,教科書上最經典的一句話是 程序是資源分配的最小單位,執行緒是cpu排程的最小單位 這句話應付考試基本上夠了,但如果在工作中遇到類似的選擇問題,那就沒有這麼簡單了,選的不好,會讓你深受其害。經常在網路上看到有的xdjm問 多程序好還是多執行緒好?linux下用多程序還是多執行緒?...

小議set與priority queue之選擇

當我們的程式中需要使用優先順序佇列時,常常考慮到兩種資料結構,set和priority queue,然後不知道用哪乙個好。先分析一下我們的需求 1.是否需要隨時從容器中刪除某項,比如乙個待釋放的資源佇列,有時我們需要放棄釋放,就要從待釋放資源佇列中刪除。2.是否需要維持佇列並依次處理,還是說佇列僅僅...

C 虛繼承之小議

c 虛繼承的作用 c 虛繼承可以防止多重繼承產生的二義性問題。虛繼承,就是在被繼承的類前面加上virtual關鍵字,這時被繼承的類稱為虛基類,如下面 中的base類。虛繼承在多重繼承的時可以防止二義性。class base class derived1 virutal public base cla...