執行緒基礎4

2021-05-11 14:15:03 字數 3215 閱讀 2551

reader-writer locks讀寫鎖:

*互斥鎖是一種簡單的保護共享資料的方式,但其並非總是最高效的,應用程式可能經常存在這樣的**:一些**更新共享資料,而另一些**僅僅讀取這些共享資料。另一些應用程式可能存在大量的讀資料行為,資料僅週期性的更新。

因為讀資料不改變任何東西,所以只要你確定在你試圖讀資料時沒有其他的執行緒在更新資料則多個執行緒同時讀取資料不會出現任何錯誤,典型地僅希望每次乙個執行緒來更新資料。***

readerwriterlock 和readerwriterlockslim物件適用於這樣的場景:允許多個併發的讀者來讀資料,但是一旦資料需要被改變,則有乙個執行緒必須臨時的互斥地訪問那個塊共享記憶體。

使用readerwriterlock 可請求乙個讀鎖或寫鎖,(鎖是作業系統資源,屬於非託管資源,謹慎使用之),如果獲取乙個讀鎖,則可以安全地讀取資料,其他的執行緒也可以獲取讀鎖並安全的讀取資料。

在想更新資料之前,必須獲取乙個寫鎖,當請求寫鎖時,任何其他的正在請求讀鎖或寫鎖的執行緒都會被阻塞。如果任何其他的讀鎖或寫鎖正在處理中(當你請求寫鎖時,正有其他的執行緒在讀或寫資料),你的執行緒會被阻塞直到它們被全部釋放。當沒有任何讀或寫鎖關聯到共享資料上時,你才可以獲取寫鎖,在你獲取寫鎖後直至你釋放寫鎖為止,其他任何鎖(讀或寫)都不會被其他的執行緒獲取,所以寫鎖是乙個互斥鎖。

在釋放寫鎖後,任何待處理的請求鎖的操作會繼續————允許僅乙個寫者或多個可同時訪問資料的讀者。使用讀寫鎖的方式同互斥鎖的方式一樣:

*****

首先建立乙個讀寫鎖的例項:

private mrwlock as new system.threading.readerwriterlock

你可以在乙個應用程式中根據需要建立多個讀寫鎖物件,

第二部使用鎖:

mrwlock.acquirewriterlock(100)

try『訪問資料

finally

'釋放鎖 在.net框架中凡是實現了dispose模式的類

'可以使用using語法,來生成try finally塊(編譯器做這些事)。

mrwlock.releasewriterlock()

end try

注意使用鎖時應該使用try finally塊,確保無論是否發生異常鎖都會被釋放。 沒有釋放鎖的後果很嚴重,可能導致應用程式部穩定甚至崩潰!!!沒有釋放鎖可能會阻塞其它執行緒,甚至是永遠阻塞這時就導致了死鎖情形,或者獲取鎖的執行緒有超時機制,特定時間範圍內沒有獲取鎖則丟擲異常導致應用程式失敗。寫鎖的使用同上:

mrwlock.acquirereaderlock(100)

try『訪問資料

finally

mrwlock.releasereaderlock()

end try

*******

.net3.5有乙個新鎖型別:readerwriterlockslim,

該類例項可提公升讀能力,前面的鎖存在一些問題如:不能自動提公升讀能力,並且效能不佳,而新的readerwriterlockslim物件給予寫更高的優先權,它假設寫鎖的獲取很少發生,所以優先機制更能提公升效能。微軟不能在前面的.net框架中修復readerwriterlock所以引入了這個新鎖,它支援的主要方法如下:

dispose: 釋放該物件持有的所以資源。

enterreadlock: 試著獲取乙個讀鎖;

enterupgradeablereadlock: 試著以公升級模式獲取乙個讀鎖;

enterwritelock:   試著獲取乙個寫鎖;

exitreadlock: 退出讀鎖;

exitupgradeablereadlock: 退出公升級模式的讀鎖。

exitwritelock: 退出寫鎖;

tryenterreadlock:讀模式下試著獲取鎖,可選可設定乙個超時。

tryenterupgradeablereadlock:在公升級讀模式下試著獲取鎖,可選設定乙個超時。

tryenterwritelock:在寫模式下試著進入鎖,可選設定乙個超時。

新的讀寫鎖支援三中模式:讀,公升級讀,和寫模式,新加入的公升級讀模式允許我們安全地在讀和寫模式下轉換。此鎖支援一種自動的公升級通道並且不會像老鎖readerwriterlock那樣導致死鎖。但是僅允許乙個執行緒進入公升級讀模式。

****

*****

autoreset events

monitor(synclock)和readerwriterlock鎖都遵從acquire/release模式,它們都可能會阻塞直到其獲取到乙個鎖。

autoresetevent 和 manualresetevent物件使得,執行緒自願選擇是否等待乙個事件物件,當等待時它們阻塞不做任何事情,當其他的執行緒激發那個事件時,等待在事件上的所有執行緒被釋放並繼續工作。

(通知與發訊號同語義)

事件物件可處在:通知的和未通知的兩種狀態之一。當事件被通知了等待在事件物件上的執行緒被釋放。如果執行緒在乙個通知的事件上呼叫waitone,則執行緒不會阻塞,如果執行緒在乙個未通知的事件上呼叫waitone則執行緒會阻塞,直到其他的執行緒呼叫物件的set方法來通知事件物件阻塞的執行緒才被解阻塞。

autoresetevent物件在任何執行緒呼叫waitone方法時自動重置其自身到未通知狀態。另一方面如果乙個autoresetevent物件未被通知則呼叫waitone的執行緒會被阻塞,其他的執行緒來呼叫set方法來通知事件物件,這會解阻塞等待中的執行緒並立即重置autoresetevent物件到未通知狀態。

我們可使用autoresetevent物件來協調使用共享資料的執行緒們:

dim mwait as new system.threading.autoresetevent(false)

false引數使得物件處於未通知狀態。而true使其處於通知(signaled)狀態,此時第乙個呼叫waitone方法的執行緒不會阻塞,但會觸發事件物件自動重置到未通知狀態。

mwait.waitone()//等待或繼續執行

mwait.set()//解阻塞其他等待的執行緒

manualresetevents的使用同autoresetevent類似。不同在於:manualresetevent使得我們完全控制事件物件的狀態到通知或未通知狀態,事件物件的狀態從來不會自動切換。

這意味著我們必須手動呼叫reset方法,而不是依賴它自動發生。這使得我們對過程有更多的控制權並可能潛在或取一些效能提公升。

dim mwait as new system.threading.manualresetevent(true)//生成乙個等待物件

mwait.waitone()

mwait.reset()

mwait.set()

linux 多執行緒基礎4

六 執行緒的作用域 函式pthread attr setscope和pthread attr getscope分別用來設定和得到執行緒的作用域,這兩個函式的定義如下 7 名稱 pthread attr setscope pthread attr getscope 功能 獲得 設定執行緒的作用域 標頭...

多執行緒基礎4 同步與通訊

1.什麼情況下需要同步 當多執行緒併發執行同一 時 希望某一段 執行的過程中cpu不要切換到其他執行緒工作.這時就需要同步.2.同步 塊 使用synchronized關鍵字加上乙個鎖物件來定義一段 這就叫同步 塊 多個同步 塊如果使用相同的鎖物件,那麼他們就是同步的 非靜態同步函式的鎖是 this ...

執行緒4 執行緒通訊

1 執行緒間的通訊主要靠三個方法 1 wait 使當前執行緒放棄cpu 物件鎖,重新排隊等待對共享資源的訪問 2 notify 喚醒等待執行緒中優先順序最高的執行緒,執行共享資源 3 notifyall 喚醒所有的等待執行緒 4 這三個方法是object裡面的方法,而非thread方法,這些方法,只...