深入淺出多執行緒系列之五 一些同步構造 上篇

2021-09-22 07:37:54 字數 2618 閱讀 1192

1:mutex

mutex 

就像乙個

c# lock

一樣,不同的是它可以跨程序.

進入和釋放乙個

mutex

要花費幾毫秒,大約比c#的

lock慢50

倍。 使用乙個

mutex

的例項,呼叫

waitone

方法來獲取鎖,

releasemutex

方法來釋放鎖。

因為mutex是跨程序的,所以我們可以使用mutex來檢測程式是否已經執行。

public

static

void

mainthread()

runprogram();}}

2:semaphore:

乙個semaphore

就像乙個酒吧一樣,通過門衛來限制它的客人,一旦到達限制,沒有人可以進入,

人們會在門外乖乖的排隊,一旦有乙個人離開酒吧,排隊中的人就可以進入了乙個了。

下面是個例子:

class

theclub

static

void

enter(

object

id)}

3:autoresetevent

乙個autoresetevent

就像十字轉門一樣,插入一張票就讓乙個人通過,

」auto」

代表門會自動的關上。

在十字門外面的人可以呼叫

waitone

方法來阻塞,等待。一旦有人插入了票(呼叫

set方法

),就可以讓外面等待的人(呼叫

waitone

方法的執行緒

)通過了。

建立autoresetevent

有乙個引數。

static

eventwaithandle _waithandle = new

autoresetevent(false);

其中false

在msdn

的解釋是:初始狀態為非終止,

按照我個人的理解

false

代表了十字轉門非終止,所以可以正常的進入,等待。

而如果是

true

的話:初始狀態為終止,也就是代表已經呼叫了set了,

就是說十字轉門已經停止了,所以接下來如果有人呼叫了

waitone

方法,這個呼叫

waitone

方法的人直接就可以進入了,不需要再插入票

(不需要呼叫

set)

了,之後的呼叫和false一致,這一點可以認為autoresetevent具有記憶功能,它記住了上次門是開啟的狀態。所以呼叫waitone方法可以進入。

class

threadautoresetevent

static

void

waiter()}

很簡單,

waiter

執行到waiting…

後,就開始呼叫

waitone

了,所以在門外排隊等待。

而主線程在睡了兩秒後,開始插入一張票

(set).

所以waiter

就繼續執行,所以列印

接下來我們使用

autoresetevent

來模擬實現生產消費問題:

class

producerconsumerqueue:idisposable

public

void

enqueuetask(

string

task)

public

void

dispose()

void

work()

if(task 

!=null

) //

如果有任務的話,執行任務

else

//否則阻塞,去睡覺吧}}

}}主線程呼叫如下:

public

static

void

main()}

4:manualresetevent:

乙個manualresetevent

就是乙個普通門,

呼叫set方法門就開啟了,允許任意數量的人進入。

呼叫waitone

方法就開始等待進入。

呼叫reset

方法門就關閉了。

在乙個關閉的門上呼叫

waitone

方法就會被阻塞。

當門下次被開啟的時候,所有等待的執行緒都可以進入了。

除了這些不同外,乙個

manualresetevent

和autoresetevent

類似。

在framework4.0

中manualresetevent

提供了乙個優化版本。

manualreseteventslim

。後面的版本速度更快,並且支援取消

(cancellationtoken).

深入淺出多執行緒系列之五 一些同步構造 上篇

1 mutex mutex 就像乙個 c lock 一樣,不同的是它可以跨程序.進入和釋放乙個 mutex 要花費幾毫秒,大約比c 的 lock慢50 倍。使用乙個 mutex 的例項,呼叫 waitone 方法來獲取鎖,releasemutex 方法來釋放鎖。因為mutex是跨程序的,所以我們可以...

深入淺出多執行緒系列之四 簡單的同步 lock

1 考慮下下面的 class threadunsafe val2 0 這段 是非執行緒安全的,假設有兩個執行緒 a,b,a,b都執行到了 go方法的 if判斷中,假設 val2 1.所以兩個執行緒 a,b都通過 if判斷,a執行了 console.writeline 方法,然後退出 if語句,執行 ...

深入淺出多執行緒系列之三 執行緒池

執行緒池 每乙個執行緒缺省會被分配 1mb的記憶體,在 c 中,這些都是實打實的分配的,當乙個執行緒啟動的時候,為了分配臨時堆疊大約需要花費幾百微秒的時間。執行緒池通過迴圈利用執行緒可以讓你更高效的利用執行緒。執行緒池就像外包的勞務隊一樣,有任務給他們,他們會管理勞務工的一切,你不需要去花時間去找單...