Linux網路程式設計 多執行緒

2021-10-03 19:06:01 字數 4573 閱讀 2518

首先多執行緒是在乙個程序內建立出多個執行緒的模型,也就是多個執行緒共用乙個程序中的資源,來實現對乙個程序中的多個事務進行處理的模型。

主線程就是通過main函式進入的執行緒,由主線程呼叫pthread_create()建立的執行緒均稱為子執行緒,每個執行緒都有自己的執行緒id,可以通過pthread_self()函式獲取

#include

intpthread_create

(pthread_t *thread,

const pthread_attr_t *attr,

void*(

*start_routine)

(void*)

,void

*arg)

; 第三個引數start_routine是乙個函式指標,它指向的函式原型是 void

*func

(void

*),這是所建立的子執行緒要執行的任務(函式);

第四個引數arg就是傳給了所呼叫的函式的引數,如果有多個引數需要傳遞給子執行緒則需要封裝到乙個結構體裡傳進去;

第乙個引數thread是乙個pthread_t型別的指標,他用來返回該執行緒的執行緒id。每個執行緒都能夠通過pthread_self

()來獲取自己的執行緒id(pthread_t型別)。

第二個引數是執行緒的屬性,其型別是pthread_attr_t型別,其定義如下:

typedef

struct

pthread_attr_t;

這裡插入乙個小的話題就是如果執行緒建立和銷毀的時間相比於要執行的任務要長的話就要涉及執行緒池的概念,

執行緒池,顧名思義,就是把一堆開闢好的執行緒放在乙個池子裡統一管理,就是乙個執行緒池,因為如果建立執行緒和銷毀執行緒的時間比執行緒處理請求的時間長,而且請求很多的情況下,會浪費大量的cpu資源在了建立和銷毀執行緒上了,所以這種方法的效率比較低,但是如果將若干已經建立完成的執行緒放在一起統一管理,如果來了乙個請求,我們從執行緒池中取出乙個執行緒來處理,處理完了放回池內等待下乙個任務,就能提公升cpu的效率,執行緒池的好處是避免了繁瑣的建立和結束執行緒的時間,有效的利用了cpu資源。

可會和與分離

可會和狀態下主線程需要明確執行等待操作,在子執行緒結束後,主線程的等待操作執行完畢,子執行緒和主線程會合,這時主線程繼續執行等待操作之後的下一步操作。在任意時刻, 可會和狀態下,執行緒可被其他執行緒收回資源。**過程需要被顯式的呼叫 pthread_detach() , 否則主程序退出子程序將進入程序的 zombie(僵死) 狀態, 其占有的部分記憶體無法**, 導致系統資源洩漏。正確使用分離函式的方法是在主線程呼叫 pthread_detach( ) ,或者在被等待執行緒中使用

pthread_detach( thread_self( ) ) 。設計多執行緒結構時應當根據實際需要, 選擇、適當的分離狀態

繫結核心

實現執行緒繫結的庫函式是 pthread_attr_setaffinity_np( ) 。該函式最後乙個引數為 mask, 對應多核處理器的掩碼。掩碼的每個設定位一一對應合法排程的處理器核, 相反, 掩碼中未設定的位則對應不可排程的處理器核。繫結的執行緒只能在對應位被設定的處理器核上行。為提高執行緒實時性, 正確使用繫結函式的方法是將有實時性需求的執行緒置位所有掩碼, 即所有處理器核均可排程。設計多執行緒結構時應當根據實際需要, 選擇具有實時任務的執行緒設定繫結屬性

執行緒優先順序排程策略

實現執行緒優先順序設定的庫函式是 pthread _attr _setschedparam ( ) 。核心的排程策略包括 sched_fifo, sched _ rr 和 sched _ other, 默 認 使 用sched_other。執行緒在 sched_other 策略下優先順序無效。為提高執行緒響應速度, 正確使用優先順序函式的方法是首先通過 pthread_attr_setschedpolicy( ) 設定核心排程策略為 sched_fifo,其次呼叫 sched_get_priority_max( ) 和 sched_get_priority_min( ) 獲取執行緒的優先順序範圍, 最後使用 pthread_attr_setschedparam( ) 設定系統合法的優先順序值

執行緒棧實現 線 程 棧 設 定 的 庫 函 數 是 pthread _ attr _setschedparam ( ) 。多執行緒共享父程序的全部資源, 建立過多數量的子執行緒將引起父程序虛擬位址空間消耗過快, 因此, 棧空間分配的合理與否是執行緒建立失敗的乙個原因, 也是執行緒執行**現故障的重要原因, 這直接導致父程序異常結束。正確使用棧函式的方法是通過管道獲取程序記憶體的利用率,在不低於主線程最低配置的條件下, 應分配給子執行緒足夠的記憶體空間。設計多執行緒結構時應當根據實際需要, 減少子執行緒的數量, 並為已有執行緒提供足夠的棧資源。

一次僅允許乙個程序使用的資源稱為臨界資源,臨界資源的使用是通過程序間互斥機制來獲得使用的

乙個訪問臨界資源(例如:共用裝置或是共用儲存器)的程式片段稱為臨界區

執行緒飢餓出現的地方:多個程序等待進入臨界區, 當臨界區可用時, 選擇哪個等待程序是任意的, 因此, 某些程序可能無限等待,形成執行緒飢餓

在使用多執行緒的時候多個執行緒可能會訪問同一塊資源, 這樣就很容易引發資料錯亂和資料安全等問題,這時候就需要保證每次只有乙個執行緒訪問這一塊資源 ,鎖-應運而生,鎖有很多種,這裡主要說一下互斥鎖,既然是互斥鎖就不可能被兩個執行緒同時獲得,乙個執行緒拿到了鎖另乙個執行緒就必須等待(這裡的鎖是阻塞鎖)。 參考博文一進入到臨界區,當臨界區可用時就直接上鎖,用完後釋放鎖

#include

#include

#include

pthread_mutex_t mutex = pthread_mutex_initializer;

int count =0;

void

*consume

(void

*arg)

return

null;}

void

*produce

(void

* arg )

return

null;}

intmain

(void

)

描述:在一張圓桌上,有n個哲學家,n支筷子,他們的生活方式只有思考和進餐迴圈進行,飢餓時便試圖取其左、右最靠近他的筷子,只有在他拿到兩支筷子時才能進餐,進餐完畢,放下筷子又繼續思考。當所有哲學家同時決定進餐,拿起左邊筷子時候,就發生了死鎖,所有的哲學家都不能同時得到兩根筷子,沒有乙個哲學家可以進餐

1)互斥條件,又稱獨佔條件。有些資源只能同時被乙個程序所占用,而其他程序不能訪問這些已被占用了的資源(哲學家的筷子)。

2)請求並保持,也稱部分分配條件。當程序等待其他資源時,仍然繼續占有已經得到的資源。

(每乙個哲學家在持有一根筷子不放的同時還再請求另一根筷子,而另一根筷子有被其他哲學家持有不放)

3)非搶占條件。程序獲得的資源未使用完之前,其他程序不能強佔,資源只能被占有它的程序自主釋放。

(如果其中任何乙個哲學家搶奪其中乙個哲學家的筷子,他就可以就餐了,就不會形成死鎖)

4)迴圈環路等待。死鎖發生時,系統中存在著一條由至少2個程序組成的環路,在這條環路中的每乙個程序都在等待後乙個程序所佔資源的釋放,因此導致環路 堵塞,使程序不能再繼續執行

(每乙個哲學家都在等待他右手邊那個哲學家的筷子資源的釋放,相互之間形成乙個環路)

一、死鎖的預防(破壞必須條件中的乙個)

1)破壞「請求並保持」條件

預分配所有共享資源。程序執行時所需的所有資源一次性申請,並且在所需資源未得到滿足之前,不執行該程序,一直等到所需資源均空閒時,再執行該程序

2)破壞「不可搶占」條件

當乙個已經持有了一些資源的程序在提出新的資源請求沒有得到滿足時,它必須釋放已經保持的所有資源,待以後需要使用的時候再重新申請。這就意味著程序已占有的資源會被短暫地釋放或者說是被搶占了。該種方法實現起來比較複雜,且代價也比較大。釋放已經保持的資源很有可能會導致程序之前的工作實效等,反覆的申請和釋放資源會導致程序的執行被無限的推遲,這不僅會延長程序的周轉週期,還會影響系統的吞吐量。

3)破壞「迴圈環路等待」條件

預防死鎖的方法是 h v a e n d s r 提出的「 有序資源使用法 」 。 把系統中所有資源類都分給乙個惟一的序號 , 把一些 經常用到的資源類排成低序號 , 不經常用到的資源類排成高序號 , 申請資源是從低序號到高序號的順序申請,資源類的序號隨系統的每次啟動動態地被修改 , 修改資源類的順序號是依據最近的和歷史的使用嵌入式系統中各資源情況 , 即根據資源類利用率表 , 使用次數最多的資源類放在序號1處 , 依次類推

二、死鎖的避免

用演算法來檢查,防止系統進入不安全轉態,典型的是銀行家演算法

三、死鎖的檢測(作業系統層面的問題)

預防和避免死鎖要求代價太高,為提高資源的利用率,作業系統一般不阻止死鎖的產生。而是採用系統定時檢測的方式,當檢測到發生死鎖時,再採取某種措施來解除死鎖

Linux多執行緒網路程式設計(一)

再次開始網路程式設計已經是乙個學期之後了。上個學期完成網路程式設計之後還沒有來得及總結,最近重新開始網路程式設計還遇到了不少的麻煩。直奔主題 在伺服器端實現的功能 1.通過tcp ip 協議,獲取客戶端傳送的檔案。2.定義了幾個簡單的指令,對客戶端進行控制。功能特點 能同時處理最多五個客戶端的請求。...

多執行緒網路程式設計

與多程序程式設計對比 1 建立多程序相比起建立多執行緒會 消耗大量的系統資源 2 程序結束比起執行緒結束,釋放的資源也更多,子程序很快結束,系統負擔加重 3.多執行緒由於在同乙個程序中,很多資源是共用的。所以執行緒間資料共享也非常高效快捷。需要注意的兩點是 1.由於多執行緒在乙個程序中,乙個程序只有...

Linux網路程式設計之多執行緒

多執行緒模型 在多執行緒模型下,注意共享資料的同步,mutex condition variable rw lock等的使用,local thread storage的使用,另外,可以搭配執行緒池處理非同步計算任務。在c 11中的執行緒庫中已經提供了future相關的工具,合理地使用執行緒模型減少資...