文章編號: 317723 - 上次校閱: 2006年12月6日 - 版次: 2.3

競爭情形和死結的描述

系統提示本文適用於您使用的作業系統之外的作業系統。與您不相關的文章內容已停用。

在此頁中

全部展開 | 全部摺疊

結論

Visual Basic.NET 或 Visual Basic 2005 提供使用 Visual Basic 應用程式中的執行緒,第一次的能力。執行緒引入偵錯問題,例如競爭情形和死結。本文探討這兩個問題。

其他相關資訊

競爭條件

當兩個執行緒同時存取共用的變數時,就會發生 競爭情形。第一個執行緒會讀取該變數,並在第二個執行緒讀取相同的值從變數。然後第一個執行緒和第二個執行緒執行在值其作業,以及它們比賽查看哪一個執行緒可以寫入值最後一個共用變數。將其值寫入執行緒的值最後會保留,因為執行緒撰寫比值上一個執行緒所撰寫。

詳細資料和範例

每個執行緒會配置一個預先定義的處理器上執行的時間期間。當配置之執行緒的時間過期時,執行緒的內容會儲存直到其下一回合對處理器,而且處理器開始下一個執行緒執行。

單行命令可以如何造成競爭情形?請檢查下列的範例,以查看競爭情形的發生。有兩個執行緒,而且兩者都更新共用的變數稱為 (表示為 dword ptr ds: [031B49DCh] 組件程式碼中)。

Visual Basic 程式碼:
   'Thread 1
   Total = Total + val1
				
   'Thread 2
   Total = Total - val2
				
組件程式碼 (與行號) 從先前的 Visual Basic 程式碼編譯:
 'Thread 1
 1.   mov         eax,dword ptr ds:[031B49DCh] 
 2.   add         eax,edi 
 3.   jno         00000033 
 4.   xor         ecx,ecx 
 5.   call        7611097F 
 6.   mov         dword ptr ds:[031B49DCh],eax 
				
 'Thread 2
 1.   mov         eax,dword ptr ds:[031B49DCh] 
 2.   sub         eax,edi 
 3.   jno         00000033 
 4.   xor         ecx,ecx 
 5.   call        76110BE7 
 6.   mov         dword ptr ds:[031B49DCh],eax 
				
依查看組譯程式碼,您可以看到多少作業處理器執行在低的層級來執行簡單的加法計算。一個執行緒可能可以在其上處理器時間執行的全部或部份其組件程式碼。現在看一下如何從這段程式碼發生競爭情形。

總和為 100、 val1 是 50,以及 val2 是 15。執行緒 1 取得要執行的機會,但只完成步驟 1 到 3。這表示執行緒 1 讀取該變數,而且完成加入。執行緒 1 現在只等候寫出的 150 其新值。執行緒 1 停止之後執行緒 2 取得完全執行。這表示它具有寫入值它計算 (85) 出至變數的總計。最後,執行緒 1 重新取得控制,並執行完畢。它會寫出它的值 (150)。因此,結束執行緒 1 後的值總計是現在代替 85 150。

您可以看到如何這可能是重大的問題。如果這是銀行程式,客戶會在不應該還存在其帳號擁有金錢。

這個錯誤是隨機,因為執行緒 1 上完成其執行之前它的時間可能處理器到期,並接著執行緒 2 開始其執行。這些事件發生就不會發生此問題。 執行緒的執行是不具決定性,因此您無法控制時間或執行的順序。同時也請注意在執行階段與偵錯模式中之執行緒可能以不同方式執行。而且,您可以看到如果您在數列中執行每個執行緒,將不會發生錯誤。這個隨機性使得這些錯誤來追蹤和偵錯很難。

若要防止發生競爭情形,可以鎖定共用的變數,以便一次只有一個執行緒有權存取共用變數。執行這項操作盡量不要,因為執行緒 2 等候執行緒 1] 到放開該變數時,如果變數鎖定在執行緒 1,且執行緒 2 也需要變數停止執行緒 2 執行。(如需詳細資訊請參閱本文 < 參考 > 一節中的"SyncLock")。

徵狀

最常見的徵狀的競爭情形是無法預期的多個執行緒之間共用的變數的值。這會造成從執行緒執行的順序 unpredictability。有時一個執行緒獲勝,有時其他執行緒獲勝。在其他時候執行正常運作。而且,如果分別執行每個執行緒,變數值行為正確。

死結

當兩個執行緒每個鎖定不同的變數在同一時間,然後再嘗試鎖定另一個執行緒已經鎖定變數時,就會發生 死結。如此一來每個執行緒會停止執行而且等待其他執行緒釋放該變數。因為每個執行緒持有另一個執行緒,想要執行任何動作發生的變數,而且執行緒保持死結。

詳細資料和範例

下列程式碼具有 LeftVal 和 RightVal 的兩個物件:
'Thread 1
SyncLock LeftVal
 SyncLock RightVal
  'Perform operations on LeftVal and RightVal that require read and write.
 End SyncLock
End SyncLock
				
'Thread 2
SyncLock RightVal
 SyncLock LeftVal
  'Perform operations on RightVal and LeftVal that require read and write.
 End SyncLock
End SyncLock
				
當允許執行緒 1 鎖定 LeftVal 時,就會發生的死結。處理器會停止執行緒 1 執行,並開始執行的執行緒 2。執行緒 2 鎖定 RightVal 然後再嘗試鎖定 LeftVal。由於鎖定 LeftVal 執行緒 2 會停止,等待 LeftVal 被釋放。因為停止執行緒 2 執行緒 1 允許繼續執行。執行緒 1 會嘗試鎖定 RightVal,但無法因為執行緒 2 已被鎖定。如此一來執行緒 1 會啟動所要等待直到 RightVal 變成可用。每個執行緒等待其他在執行緒因為每一個執行緒已鎖定另一個執行緒正在等候,變數,既非執行緒已解除鎖定它持有的變數。

永遠不會發生死結。如果執行緒 1 執行這兩個鎖定之前,處理器會停止它,執行緒 1 可執行其作業,然後再解除鎖定共用的變數。執行緒 1 會解除鎖定變數之後執行緒 2 可以繼續使用其執行,如預期般運作。

這些程式碼片段的程式碼會放在並排顯示,但在練習中,程式碼可能會出現在個別的模組或程式碼的區域時,這項錯誤似乎明顯。這是很難錯誤追蹤因為從這個相同的程式碼正確執行和不正確的執行可能會發生。

徵狀

死結的常見徵狀是程式或群組的執行緒會停止回應。這也稱為是 掛掉 了。至少兩個執行緒是每個正在等待另一個執行緒鎖定的變數。執行緒不會繼續,因為兩個執行緒會釋放其變數,取得其他變數之前。整個程式可以停止回應,如果一個或兩個完整執行那些執行緒正在等候程式。

執行緒是什麼?

處理程序用來分隔不同在指定的時間,在單一電腦上執行的應用程式。作業系統將不會執行處理程序,但執行緒執行。執行緒是執行的單位。作業系統會配置供執行緒的工作執行執行緒的處理器時間。單一處理序可以包含多個執行緒的執行。每一個執行緒都會維護排程優先順序,以及一組結構作業系統用來儲存執行緒的內容,如果執行緒無法完成它被指派給處理器期間其執行它自己的例外處理常式。內容會保留到下次執行緒接收到處理器時間。內容包含執行緒需要不著痕跡地繼續其執行的所有資訊。這項資訊包括執行緒的一組處理器暫存器和主機處理序位址空間內呼叫堆疊。

?考

如需詳細資訊搜尋 Visual Studio 說明下列關鍵字:
  • SyncLock。允許物件已被鎖定。如果另一個執行緒嘗試鎖定該相同的物件,它就會封鎖,直到第一個執行緒釋放。使用 SyncLock 仔細,因為問題可能起因於 SyncLock 誤用。比方說這個命令可以預防競爭情形,但是導致死結。
  • 連鎖。允許一組選定的基本數值的變數上的安全執行緒的作業。
如需詳細資訊按一下面的文件編號,檢視 「 Microsoft 知識庫 」 中的發行項:
316422? (http://support.microsoft.com/kb/316422/EN-US/ ) 在 Visual Basic.NET 中的執行緒處理的資訊: 藍圖
如需詳細資訊請參閱下列 MSDN 網站:
Threads and Threading (http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpguide/html/cpconthreadsthreading.asp)

這篇文章中的資訊適用於:
  • Microsoft Visual Basic 2005
  • Microsoft Visual Basic .NET 2003 Standard Edition
  • Microsoft Visual Basic .NET 2002 Standard Edition
關鍵字:?
kbmt kbvs2005swept kbvs2005applies kbinfo KB317723 KbMtzh
機器翻譯機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:317723? (http://support.microsoft.com/kb/317723/en-us/ )
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。