C 夯實基礎之多執行緒三 執行緒的優先順序

2022-02-10 09:40:41 字數 2548 閱讀 4681

一.為什麼需要優先順序--執行緒排程的問題

在現實生活中,優先順序是乙個很常見的現象:在火車站,如果你是孕婦,你是可以走進站中的專門綠色通道的,可以提前上火車以免擁擠;火警

119匪警

110出警的時候,都是人命關天的大事,是可以優先使用道路的,行人和車輛一律避讓;在銀行,如果你是白金

vip,也會有專門的綠色通道供你使用

.從社會公平層面的優先順序,到商業活動中的優先順序,大家每天都生活在這樣的環境之中,而且是按照這套遊戲規則行事。

windows是乙個使用者作業系統,在設計上遵循著穩定性為準則,也就是說他要與人類的思維方式保持一致,才能用得舒服,執行緒的優先順序可以說就是這一原則下的產物

.如果都讓車輛在路上一直依次行駛,那麼

120到現場的時候,人都可能已經掛了;如果病毒一直搶占

cpu,那防毒軟體也就沒有什麼卵用了。

這裡需要注意現實生活中優先順序與windows中優先順序的不同之處,現實生活中,我們可以通過新增資源(如增加視窗)優先處理高階別的業務,也可以通過對共同資源的排程(如110出警)來處理優化優先順序高的業務。windows則是在借鑑這些思路的時候進行了自己的一些改造,如排程佇列、動態優先順序調整等。

二.了解windows的執行緒排程

windows進化到現在,已經是乙個時分和搶占式作業系統,它不同於實時作業系統,它通過動態地調整執行緒等待佇列,從而確定執行緒使用

cpu時間片的順序。優先順序高的執行緒有更大的概率排在佇列的前面,同時獲得更多數量的時間片,而不是更長時間的時間片。

執行緒如果被sleep掉、等待

io時,會釋放他所擁有的

cpu,如果執行緒不是主動釋放

cpu,執行緒排程器會搶占該執行緒。如果優先順序相同的多個執行緒等待使用

cpu,則會使用乙個迴圈排程規則來實現佇列的先後順序。

前面我們說過優先順序是動態調整的,優先順序低的不可能一直都是在等待,隨著時間的運轉,低優先順序執行緒的優先順序會提公升,這樣執行緒才有可能在等待結束時獲得cpu。

再次強調,執行緒優先順序只是提高了執行緒被呼叫的概率,並不是定義cpu呼叫執行緒的順序,具體的工作就交給作業系統內部了。

三.c#中的執行緒優先順序

c#中為我們提供了

5個執行緒優先級別,如下所示:

9 }結果如下:

四.優先順序反轉

這裡要用到鎖的知識,對這塊有疑問的可以先去大致了解下鎖。

假設一種情況,執行緒a是高優先順序執行緒,執行緒

b是低優先順序執行緒,執行緒

b等啊等,終於等到自己,然後它鎖住了乙個資源

r,然後執行緒

a接手,但是它要用到r,

r被鎖,然後

a只有等待

b釋放鎖,然而

b優先順序低,它只有經過漫長的等待才能提高自己的優先順序得到執行,而此時

a仍然在等待

b釋放鎖,從表而看執行緒

a是有非常多的執行機會,但執行緒

a並未執行任何**,反而

b一直在執行,那麼執行緒

a何時能夠得到資源呢?不知道,原來的優先順序設定也就失去了意義。這就是所謂的優先順序反轉。

那麼,如何避免這一問題呢?這裡給出一些建議。

1.鎖的尺寸應該盡量小,就是使用小鎖而非大鎖,比如鎖定字串就是乙個非常大的鎖

2.鎖的**應該盡量短,這樣鎖定的時間就會盡量少

3.可以使用原子鎖

使用優先順序繼承:也就是,高優先順序程序th

在等待低優先順序的執行緒tl占用的競爭資源時,為了使th

能夠盡快獲得排程執行,由作業系統把tl

的優先順序提高到th

的優先順序,從而讓tl

以th的優先順序參與排程,盡快讓tl

執行並釋放掉th

欲獲得的競爭資源,然後tl的優先順序調整到繼承前的水平,此時th

可獲得競爭資源而繼承執行。優先順序繼承還可以存在傳遞性,也就是說tl

還需要更低的低優先順序執行緒tm

的同步資源時,也會把tm

的執行緒優先順序拉高到tl,這要看各個作業系統的具體實現。

五.結尾

在做應用程式時,我們建議,盡量不去干預執行緒的優先順序,把排程的順序交給作業系統處理就好。

六.參考

《c#高階程式設計(第7版)》

部落格  

部落格  

多執行緒系列(三) 執行緒池基礎

目錄 一 為什麼要使用執行緒池 執行緒池概念理解 備註 執行緒池中的執行緒是後台執行緒。1 為什麼會有執行緒池?因為建立執行緒和銷毀執行緒相對來說需要消耗大量的時間和資源。太多的執行緒會浪費記憶體。2 執行緒池是什麼?執行緒池就是乙個可持續性發展的執行緒集合,執行緒池內部維護著乙個訊息佇列。當一條方...

APUE學習之多執行緒程式設計(三) 執行緒屬性 同步屬性

一 執行緒屬性 可以使用pthread attr t結構修改執行緒預設屬性,並這些屬性和建立的執行緒練習起來,可以使用pthread att init函式初始化pthread attr t結構,呼叫pthread attr init後,pthread attr t結構所包含的就是作業系統實現支援的所...

C 多執行緒程式設計 三 執行緒間通訊

七 執行緒間通訊 一般而言,應用程式中的乙個次要執行緒總是為主執行緒執行特定的任務,這樣,主線程和次要執行緒間必定有乙個資訊傳遞的渠道,也就是主線程和次要執行緒間要進行通訊。這種執行緒間的通訊不但是難以避免的,而且在多執行緒程式設計中也是複雜和頻繁的,下面將進行說明。使用全域性變數進行通訊 由於屬於...