從公交塞車,看C 多執行緒同步問題

2022-01-15 07:01:22 字數 3384 閱讀 1707

好久沒寫部落格了,可能是因為最近工作太過於壓抑的原因吧!有點頹廢了.... 而且公司距離住處要坐公交將近40--50分鐘(各個原因,糾結中ing...),提前乙個半小時起床,居然還能遲到!因為距離公司前兩站是個十字路口,每天能在**塞上30多分鐘....眼看就要到公司了,一輛接一輛阻塞著..看著時間一分一秒的過去..心裡不盡拔涼起來(遲到會扣錢的!)... 拔涼之餘不禁讓我想到c#中線程的同步非同步.所以呈此博文,來談談我對c#中線程同步的理解,不當之處,請大家多多指點,在此先謝謝了!

什麼是執行緒同步? 多個執行緒同時執行時,可能會因為執行緒之間的邏輯關係而決定誰先執行,誰後執行, 這就是執行緒同步。

(1)執行緒的優先順序

當執行緒之間爭奪cpu時間片時,cpu是按照執行緒的優先順序進行服務的。在c#應用程式中,執行緒有5個不同的優先順序,由高到低分別是:highest、abovenormal、normal 、belownormal和lowest。建立執行緒時,如果不指定其優先順序,則系統預設為normal。

如:thread t = new thread(methodname);

t.priority = threadpriority.abovenormal;

通過設定執行緒的優先順序可以改變執行緒執行的順序,所設定的優先順序僅僅適用於這些執行緒所屬的程序。(注:當把某個執行緒的優先順序設定為htghest時,系統上正在執行的其他執行緒都會終止,所以使用這個優先順序的時候要特別小心。除非遇到「幣需」馬上處理的任務,否則不要使用這個優先順序)。

(2)執行緒同步

多執行緒處理解決了吞吐量和響應速度的問題,但同時也帶來了資源共享問題,如死鎖和資源爭用。多執行緒特別適用於需要不同的資源(如檔案控制代碼和網路連線)的任務。為單個資源分配多個執行緒可能會導致同步問題,這種情況下,執行緒可能會北頻繁阻止以等待其他執行緒,從而使用多執行緒的初衷背道而馳。

所謂同步,是指多個執行緒之間存在先後執行順序的關聯關係。如果乙個執行緒必須在另乙個執行緒完成某個工作後才能繼續執行,則必須考慮如何讓其他保持同步,以確保在系統上同時執行多個執行緒而不會出現死鎖或邏輯錯誤。

為了解決同步問題,一般使用輔助線程執行不需要大量占用其他執行緒所使用的資源的耗時任務或時間要求緊迫的任務。但實際上,程式中的某些資源必須由多個執行緒訪問。為了解決這些問題,system.threading命名空間提供了多個用於同步執行緒的類。這些類包括mutex,monitor,interlocked,autoresetevent.  但是實際應用程式中,我們使用最多的可能不是這些類,而是c#提供的lock語句。

lock語句

為了在多執行緒應用程式中讓同步變得簡單,c#專門提供了乙個lock語句。lock關鍵字能確保當乙個執行緒位於**的臨界區時,另乙個執行緒不進入臨界區。如果其他執行緒試圖進入鎖定的**段,則它將一直等待(阻塞),知道鎖定的物件被釋放以後才能進入臨界區。

private

object obj

=new

object();

.....

lock(obj)

舉個例子相信大家會更明白,路人甲和路人乙要上廁所,剛好找到了乙個公共廁所,杯具的是公共廁所裡面只有乙個位置,路人甲是會員(優先順序高),先溜進去了,然後把門鎖上(lock)緊接著裡面發出一陣陣巨響....(大家都懂的,最近食物不敢亂吃啊 - -!)。路人乙可著急了,捂著肚子,在外面打轉,憋得面紅耳赤!過了好一段時間,路人甲抽著香菸,吹著口哨,從廁所裡面走出來(lock解鎖了),路人乙急忙鑽進去,緊接著又是一陣巨響.....

雖然這個例子舉的有點不和諧,但相信大家已經弄明白lock的作用了。

值得注意的是:1、鎖定的物件名(上面的obj),一般宣告為object型別,注意不要將其宣告為值型別,物件名叫什麼無所謂,只要符合物件命名原則就行。2、一定要將該object型別的物件名宣告為private(私有),不能將其宣告為public(公共),否則將會使lock語句無法控制,從而引發一系列的問題。 (就像上面舉例一樣:漆黑不見五指的夜晚(沒電),路人乙解開褲帶,正準備蹲下時,乙隻手把路人乙的pp托住,喊道:有人!- -#。

)3、處於臨界區的**不宜太多。如果在鎖定和解鎖期間處理的**過多,由於某個執行緒執行臨界區中的**時,其他等待執行臨界區中**的執行緒都會處於阻塞狀態,這樣就可能會降低應用程式的效能。(路人乙會恨死路人甲的!)

好了,閒話就說這麼多,還是拿**說事吧,說過隨機取款的例子。

(2)新增乙個類:account.cs。**如下:

class account

/// /// withdraws the specified amount.

///

/// the amount.

///

private int withdraw(int amount)

//將lock(lockedobj)這句話注視掉,看看會發生什麼情況

lock (obj)

取款:",balance,amount);

balance = balance - amount;

str += "取款前餘額:" + balance;

form1.addlistboxitem(str);

return amount;

}else}}

public void dotransactions()}}

public

partial

class

form1 : form

private

void

btnlock_click(

object

sender, eventargs e)

for(

inti =0

; i

<

10; i++)

}delegate

void

addlistboxitemdelegate(

string

str);

public

void

addlistboxitem(

string

str)

else

}}

(4)按編譯並執行,單擊 「開始自動隨機取款」按鈕,觀察執行緒執行後在listbox中新增的可能出現的內容,如圖:

(5) 將lock(obj)這條語句注視掉,再次執行程式,觀察執行緒執行後在listbox中新增的可能出現的內容,如圖:

好了,對執行緒同步問題和解決同步問題的理解,就先寫道這裡,上述不當之處,希望大家多多指點,共同進步。

C 多執行緒執行緒同步問題

程序通常被定義為乙個正在執行的程式的例項,是乙個程式在其自身位址空間中的一次執行活動。程序從來不執行任何東西,它是執行緒的容器。若要程序完成某項操作它必須擁有乙個在它的環境中執行的執行緒,此執行緒負責包含執行包含在程序位址空間中的 現存由執行緒的核心物件和執行緒棧兩部分組成。作業系統用執行緒的核心物...

多執行緒同步問題

在應用程式中使用多個執行緒的乙個好處是每個執行緒都可以非同步執行。對於 windows 應用程式,耗時的任務可以在後台執行,而使應用程式視窗和控制項保持響應。對於伺服器應用程式,多執行緒處理提供了用不同執行緒處理每個傳入請求的能力。否則,在完全滿足前乙個請求之前,將無法處理每個新請求。然而,執行緒的...

多執行緒同步問題

有四個執行緒1,2,3,4,執行緒1的功能就是輸出1,執行緒2的功能就是輸出2,以此類推.現在有四個檔案.abcd.初始都為空.現要讓四個檔案呈如下格式 a 1 2 3 4 1 2.b 2 3 4 1 2 3.c 3 4 1 2 3 4.d 4 1 2 3 4 1.設計程式.include sys ...