分享方式:


在 Visual Studio 中對多執行緒應用程式進行偵錯

執行緒是作業系統授與處理器時間的指令序列。 在作業系統中執行的每個處理序都包含至少一個執行緒。 具有一個以上執行緒的處理序就稱為多執行緒。

具有多個處理器、多核心處理器或超執行緒處理器的電腦,可以執行數個同時的執行緒。 使用許多執行緒的平行處理可以大幅改善程式效能,但也可能會使偵錯更加困難,因為您正在追蹤許多執行緒。

但是並非都能達到完美的平行處理境界。 執行緒有時候必須進行同步處理。 一個執行緒可能需要等候其他執行緒的結果,或是一個執行緒可能需要其他執行緒正在使用之資源的獨佔存取權。 同步處理是多執行緒應用程式中發生錯誤的常見原因。 有時候執行緒會演變成一直在等候永遠無法使用的資源。 這會導致所謂的「死結」情況。

執行緒和流程

「執行緒」和「處理序」在電腦科學中是相關的概念。 兩者都代表必須以特定順序執行的指令序列。 但是,不同執行緒或處理序中的指令能夠平行執行。

處理序存在於作業系統中,並對應至所謂的程式或應用程式。 從另一方面來說,執行緒存在於處理序中。 基於這個原因,執行緒有時候會稱為「輕量處理序」。 每個處理序是由一或多個執行緒組成。

具有多個處理序能夠讓電腦同時執行一項以上的工作。 具有多個執行緒能夠讓處理序分割工作以平行方式執行。 使用多個處理器的電腦能夠在不同的處理器上執行處理序或執行緒。 如此可達到真正的平行處理。

偵錯多執行緒應用程式的工具

Visual Studio 提供不同工具,用於偵錯多執行緒應用程式。

Visual Studio 也會提供強大的中斷點和追蹤點,這在您偵錯多執行緒應用程式時很有用。 使用中斷點條件和篩選條件,將中斷點放置在個別執行緒上。 追蹤點可讓您追蹤程式的執行,而不會中斷研究死結等問題。 如需詳細資訊,請參閱中斷點動作與追蹤點

偵錯具有使用者介面的多執行緒應用程式可能會特別地困難。 您可能會考慮在第二部電腦上執行應用程式,並使用遠端偵錯。 如需詳細資訊,請參閱遠端偵錯

下表顯示在這些位置中可用的資訊與能夠執行的動作:

使用者介面 可用的資訊 能夠執行的動作
[附加至處理序] 對話方塊 能夠附加至的可用處理序:

- 處理序名稱 (.exe)
- 處理序識別碼
- 功能表列標題
- 類型 (受控 v4.0;受控 v2.0、v1.1、v1.0;x86;x64;IA64)
- 使用者名稱 (帳戶名稱)
- 工作階段編號
選取要附加至的處理序

選取遠端電腦

變更連接至遠端電腦的傳輸類型
[處理序] 視窗 附加之處理序:

- 處理序名稱
- 處理序識別碼
- 處理序 .exe 的路徑
- 功能表列標題
- 狀態 (中斷、執行)
- 偵錯 (原生、受控等。)
- 傳輸類型 (預設、未經驗證的機器碼)
- 傳輸限定詞 (遠端電腦)
工具:

- 附加
- 中斷連結
- 終止

捷徑功能表:

- 附加
- 中斷連結
- 當偵錯停止時中斷連結
- 終止
[執行緒] 視窗 目前處理序中的執行緒:

- 執行緒識別碼
- 受控識別碼
- 分類 (主執行緒、介面執行緒、遠端程序呼叫處理常式或背景工作執行緒)
- 執行緒名稱
- 建立執行緒的位置
- 優先權
- 親和性遮罩
- 暫停計數
- 處理序名稱
- 旗標指標
- 暫停指標
工具:

- 搜尋
- 搜尋呼叫堆疊
- 將 Just My Code 加上旗標
- 將自訂模組選取範圍加上旗標
- 分組依據
- 資料行
- 展開/摺疊呼叫堆疊
- 展開/摺疊群組
- 凍結/解除凍結執行緒

捷徑功能表:

- 在原始程式碼中顯示執行緒
- 切換至執行緒
- 將執行中的執行緒凍結
- 將執行緒解除凍結
- 爲執行緒加上旗標以利進一步研究
- 取消執行緒的旗標
- 重新命名執行緒
- 顯示和隱藏執行緒

其他動作:

- 在 DataTip 中檢視執行緒的呼叫堆疊
來源視窗 左側巡覽邊上的執行緒指示器能指出是單一或多個執行緒 (預設為關閉,可使用 [執行緒] 視窗中的捷徑功能表開啟) 捷徑功能表:

- 切換至執行緒
- 爲執行緒加上旗標以利進一步研究
- 取消執行緒的旗標
[偵錯位置] 工具列 - 目前的處理序
- 暫停應用程式
- 繼續執行應用程式
- 暫停並關閉應用程式
- 目前的執行緒
- 切換目前執行緒的旗標狀態
- 僅顯示有旗標的執行緒
- 僅顯示目前處理序
- 目前的堆疊框架
- 切換至另一個處理序
- 暫停、繼續或關閉應用程式
- 切換至目前處理序中的另一個執行緒
- 切換至目前執行緒中的另一個堆疊框架
- 將目前執行緒加上旗標或取消旗標
- 僅顯示有旗標的執行緒
- 僅顯示目前處理序
[平行堆疊] 視窗 - 一個視窗中多個執行緒的呼叫堆疊。
- 每個執行緒的作用中堆疊框架。
- 任何方法的呼叫端和被呼叫端。
- 死結偵測
- 篩選掉指定的執行緒
- 篩選掉外部程式碼堆疊
- 切換至工作檢視
- 將執行緒加上旗標或取消旗標
- 縮放
- 複製堆疊框架
- 將所有堆疊儲存/匯出為映像
[平行監看式] 視窗 - 旗標資料行,您可以在該資料行中標示想要特別注意的執行緒。
- 框架資料行,其中的箭號表示所選的框架。
- 可以顯示電腦、處理序、磚、工作和執行緒的可設定資料行。
- 將執行緒加上旗標或取消旗標
- 僅顯示已加上旗標的執行緒
- 切換框架
- 排序資料行
- 群組執行緒
- 將執行緒凍結或解除凍結
- 匯出 [平行監看式] 視窗中的資料
[工作] 視窗 - 檢閱 Task 物件的相關資訊,包括工作識別碼、工作狀態 (已排程、執行中、等待中、死結),以及指派給工作的執行緒。
- 呼叫堆疊中的目前位置。
- 在建立時傳遞至工作的委派
- 切換至目前工作
- 將工作加上旗標或取消旗標
- 將工作凍結或解除凍結
[GPU 執行緒] 視窗 - 旗標資料行,您可以在該資料行中標示想要特別注意的執行緒。
- 目前的執行緒資料行,其中黃色箭號表示目前的執行緒。
- [執行緒計數] 資料行,可顯示同一位置的執行緒數目。
- [行] 資料行,可顯示每個執行緒群組所在的程式碼行。
- [位址] 資料行,可顯示每個執行緒群組所在的指令位址。
- [位置] 資料行,是位址在程式碼中的位置。
- [狀態] 資料行,可顯示執行緒為使用中或已封鎖。
- [磚] 資料行,可顯示資料列中執行緒的磚索引。
- 變更為不同的執行緒
- 顯示特定磚和執行緒
- 顯示或隱藏資料行
- 依資料行排序
- 群組執行緒
- 將執行緒凍結或解除凍結
- 將執行緒加上旗標或取消旗標
- 僅顯示已加上旗標的執行緒