c#的多執行緒機制探索(3.1)
2007-04-03 15:51
三.執行緒的同步和通訊——生產者和消費者
假 設這樣一種情況,兩個執行緒同時維護乙個佇列,如果乙個執行緒對佇列中新增元素,而另外乙個執行緒從佇列中取用元素,那麼我們稱新增元素的執行緒為生產者,稱取用 元素的執行緒為消費者。生產者與消費者問題看起來很簡單,但是卻是多執行緒應用中乙個必須解決的問題,它涉及到執行緒之間的同步和通訊問題。
前面說過,每個執行緒都有自己的資源,但是**區是共享的,即每個執行緒都可以執行相同的函式。但是多執行緒環境下,可能帶來的問題就是幾個執行緒同時執行乙個函式,導致資料的混亂,產生不可預料的結果,因此我們必須避免這種情況的發生。
c#提供了乙個關鍵字
lock
,它可以把一段**定義為互斥段(
critical section
),互斥段在乙個時刻內只允許乙個執行緒進入執行,而其他執行緒必須等待。在
c#中,關鍵字
lock
定義如下:
lock(expression) statement_block
expression
代表你希望跟蹤的物件,通常是物件引用。一般地,如果你想保護乙個類的例項,你可以使用
this
;如果你希望保護乙個靜態變數(如互斥**段在乙個靜態方法內部),一般使用類名就可以了。而
statement_block
就是互斥段的**,這段**在乙個時刻內只可能被乙個執行緒執行。
下面是乙個使用
lock
關鍵字的典型例子,我將在注釋裡向大家說明
lock
關鍵字的用法和用途:
//lock.cs
using system;
using system.threading;
internal class account
internal int withdraw(int amount)
//下面的**保證在當前執行緒修改
balance
的值完成之前
//不會有其他執行緒也執行這段**來修改
balance
的值//
因此,balance
的值是不可能小於0的
lock (this)
else }}
internal void dotransactions()
} internal class test
for (int i = 0; i < 10; i++)
threads[i].name=i.tostring();
for (int i = 0; i < 10; i++)
threads[i].start();
console.readline();}}
而多執行緒公用乙個物件時,也會出現和公用**類似的問題,這種問題就不應該使用
lock
關鍵字了,這裡需要用到
system.threading
中的乙個類
monitor
,我們可以稱之為監視器,
monitor
提供了使執行緒共享資源的方案。
monitor
類可以鎖定乙個物件,乙個執行緒只有得到這把鎖才可以對該物件進行操作。物件鎖機制保證了在可能引起混亂的情況下乙個時刻只有乙個執行緒可以訪問這個物件。
monitor
必須和乙個具體的物件相關聯,但是由於它是乙個靜態的類,所以不能使用它來定義物件,而且它的所有方法都是靜態的,不能使用物件來引用。下面**說明了使用
monitor
鎖定乙個物件的情形:
......
queue oqueue=new queue();
......
monitor.enter(oqueue);
......//
現在oqueue
物件只能被當前執行緒操縱了
monitor.exit(oqueue);//
釋放鎖
如上所示,當乙個執行緒呼叫
monitor.enter()
方法鎖定乙個物件時,這個物件就歸它所有了,其它執行緒想要訪問這個物件,只有等待它使用
monitor.exit()
方法釋放鎖。為了保證執行緒最終都能釋放鎖,你可以把
monitor.exit()
方法寫在
try-catch-finally
結構中的
finally
**塊裡。對於任何乙個被
monitor
鎖定的物件,記憶體中都儲存著與它相關的一些資訊,其一是現在持有鎖的執行緒的引用,其二是乙個預備隊列,佇列中儲存了已經準備好獲取鎖的執行緒,其三是乙個等待佇列,佇列中儲存著當前正在等待這個物件狀態改變的佇列的引用。當擁有物件鎖的執行緒準備釋放鎖時,它使用
monitor.pulse()
方法通知等待佇列中的第乙個執行緒,於是該執行緒被轉移到預備隊列中,當物件鎖被釋放時,在預備隊列中的執行緒可以立即獲得物件鎖。
C 的多執行緒機制探索
c 的多執行緒機制探索 與threadpool類不同,timer類的作用是設定乙個定時器,定時執行使用者指定的函式,而這個函式的傳遞是靠另外乙個 物件timercallback,它必須在建立timer物件時就指定,並且不能更改。定時器啟動後,系統將自動建立乙個新的執行緒,並且在這個執行緒裡執行使用者...
C 的多執行緒機制探索4
expression代表你希望跟蹤的物件,通常是物件引用。一般地,如果你想保護乙個類的例項,你可以使用this 如果你希望保護乙個靜態變數 如互斥 段在乙個靜態方法內部 一般使用類名就可以了。而statement block就是互斥段的 這段 在乙個時刻內只可能被乙個執行緒執行。using syst...
C 的多執行緒機制探索中
expression代表你希望跟蹤的物件,通常是物件引用。一般地,如果你想保護乙個類的例項,你可以使用this 如果你希望保護乙個靜態變數 如互斥 段在乙個靜態方法內部 一般使用類名就可以了。而statement block就是互斥段的 這段 在乙個時刻內只可能被乙個執行緒執行。using syst...