C 多執行緒中鎖的使用

2021-07-03 22:13:06 字數 1269 閱讀 5303

最近的專案中涉及到實時資料的處理,經常會使用多執行緒訪問共享資源。如果處理不當,資源未能正確在各個執行緒中同步的話,計算結果將會出現錯誤。

關於資源同步最常用的技術就是加鎖。這裡提到是乙個比較簡單的鎖 -- lock。 lock是對monitor中的兩個函式enter和exit的封裝。

當時專案的模式是這樣的:有乙個類中有個共享的資源(list),這個類會開闢兩個執行緒分別對它進行讀和寫操作,而且這個類會有多個例項,每個例項都會在乙個執行緒中。

其工作模式如下圖所示:

這裡的寫執行緒將會動態改變list裡面的值已經值對應的index,而讀的執行緒會先用乙個匹配的函式找出需要的值對應的index,然後根據index取出其中的值加以計算。

在這種模式中,如果讀執行緒去訪問list資料時,寫執行緒對list進行了修改,就會導致結果出錯。因此我們需要引入鎖的機制。那麼問題來了,我們是要在讀的執行緒中加鎖,還是在寫的執行緒中加鎖。而且加鎖的話,是採用什麼方式?

以下有幾種方式,將會一一分析其對錯。

1. 使用物件本身作為鎖物件,對寫執行緒進行加鎖

使用這種方式,在寫執行緒中,list將會被鎖定,執行完畢之後釋放鎖。然而這種模式還是會得出錯誤結果,假設在讀執行緒中先對list進行了匹配並取出了需要的index,這時寫執行緒獲取了鎖,並對list進行了修改,之後釋放list,讀執行緒根據index查詢list對應的值,然而此時list已被更改。

2. 使用物件本身作為鎖物件,對讀執行緒進行加鎖

使用這種方式,在讀執行緒中,list將會被鎖定,所以讀的過程中list都將保持不變。

除了使用物件本身作為鎖物件之外,還可以使用其他的引用型別,比如system.object,此時執行緒不會訪問該型別的任何屬性和方法,改物件的作用僅僅是協調各個執行緒。

3. 使用system.object作為鎖物件

根據上面的分析,我們將只對讀執行緒進行加鎖。但是這時又有兩種情況:object物件可以定義成例項物件和靜態物件。目前的這種模式適用於把鎖加在例項物件的object上。因為使用object作為鎖物件時,操作流程時占有a,操作b,釋放a。若將object定義為靜態物件,此時對object進行加鎖,將協調的是類的每個例項所產生的物件,對應的list也必須是靜態的。而這裡我們需要協調的是某乙個例項中的兩個執行緒,因此需要將object定義為例項物件。

綜上所述,有兩種方式可以實現以上模式的執行緒同步,一種是使用物件本身作為鎖物件,對讀執行緒進行加鎖,另一種是使用例項物件的system.object作為鎖物件,對讀執行緒程序加鎖。

多執行緒中鎖的使用

執行緒之間的鎖有 互斥鎖 條件鎖 自旋鎖 讀寫鎖 遞迴鎖。一般而言,鎖的功能越強大,效能就會越低。1 互斥鎖 互斥鎖用於控制多個執行緒對他們之間共享資源互斥訪問的乙個訊號量。也就是說是為了避免多個執行緒在某一時刻同時操作乙個共享資源。例如執行緒池中的有多個空閒執行緒和乙個任務佇列。任何是乙個執行緒都...

多執行緒中鎖的使用

本文 主要介紹下c 的兩種鎖 互斥鎖 lock 和讀寫鎖 readwritelock 互斥鎖 lock lock 關鍵字將語句塊標記為臨界區,方法是獲取給定物件的互斥鎖,執行語句,然後釋放該鎖。當任何乙個執行緒獲取到鎖後,其他執行緒如果需要使用該臨界區內 則必須等待前乙個執行緒使用完畢後釋放鎖。示例...

多執行緒中的鎖

導致死鎖的原因 有兩個或多個執行緒需要在幾個共享物件上獲取鎖,這可能會導致死鎖。thread1 object1 object2 thread2 object2 object1 死鎖的四個條件 1.互斥條件 2.不可剝奪條件 3.請求與保持條件 4.迴圈等待條件 解決方式 1.避免滿足產生死鎖的四個條...