線程是作系統授與處理器時間的一連串指示。 在作系統中執行的每個進程都至少包含一個線程。 具有多個線程的進程稱為多線程。
具有多個處理器、多核心處理器或超線程進程的計算機可以執行數個同時線程。 使用許多線程的平行處理可以大幅改善程式效能,但也可能會使偵錯更加困難,因為您正追蹤許多線程。
完美的平行處理不一定可行。 線程有時必須同步處理。 一個線程可能必須等候另一個線程的結果,或者某個線程可能需要另一個線程正在使用的資源獨佔存取權。 同步處理問題是多線程應用程式中 Bug 的常見原因。 有時候線程最終可能會等待永遠不會變成可用的資源。 這會導致稱為 死結的條件。
線程和進程
線程 和 進程 是計算機科學的相關概念。 兩者都代表必須依特定順序執行的指令序列。 不過,個別線程或進程中的指示可以平行執行。
程式存在於作系統中,並對應至使用者視為程式或應用程式的內容。 另一方面,線程存在於進程內。 因此,線程有時稱為 輕量進程。 每個進程都包含一或多個線程。
有多個進程的存在可讓計算機一次執行多個工作。 存在多個線程可讓進程以平行方式執行工作。 在具有多處理器的計算機上,進程或線程可以在不同的處理器上執行。 這可啟用真正的平行處理。
偵錯多線程應用程式的工具
Visual Studio 提供用於偵錯多線程應用程式的不同工具。
針對線程,偵錯線程的主要工具是 [平行堆棧 ] 視窗、[ 平行監看 式] 視窗、來源視窗中的線程標記、[ 線程 ] 視窗和 [ 偵錯位置] 工具列。 若要瞭解平行堆疊中的線程檢視,請參閱使用線程檢視對死結進行偵錯。 若要瞭解如何使用 平行堆疊 和 平行監看 式視窗,請參閱 開始偵錯多線程應用程式。 入門文章說明如何使用線程標記。 另請參閱 逐步解說:偵錯C++ AMP 應用程式。
對於使用異步的 .NET 程式代碼,用於偵錯的主要 工具是[平行堆棧 ] 視窗中的工作檢視。 若要開始使用,請參閱 偵錯異步應用程式 (.NET) 。
針對線程,偵錯線程的主要工具是 [平行堆棧 ] 視窗、[ 平行監看 式] 視窗、來源視窗中的線程標記、[ 線程 ] 視窗和 [ 偵錯位置] 工具列。 若要瞭解平行堆疊中的線程檢視,請參閱在 [平行堆棧] 視窗中檢視線程和工作。 若要瞭解如何使用 平行堆疊 和 平行監看 式視窗,請參閱 開始偵錯多線程應用程式。 入門文章說明如何使用線程標記。 另請參閱 逐步解說:偵錯C++ AMP 應用程式。
對於使用異步的 .NET 程式代碼,用於偵錯的主要 工具是[平行堆棧 ] 視窗中的工作檢視。 如需詳細資訊,請參閱在平行堆疊視窗中檢視執行緒和工作。
針對 GPU 上的線程進行偵錯,主要工具是 [GPU 線程] 視窗。 請參閱 如何:使用 [GPU 線程] 視窗。
針對進程,主要工具是 [ 附加至進程 ] 對話框、[ 進程 ] 視窗和 [ 偵錯位置] 工具列。
Visual Studio 也提供功能強大的斷點和追蹤點,當您偵錯多線程應用程式時,這非常有用。 使用斷點條件和篩選條件,將斷點放在個別線程上。 追蹤點可讓您追蹤程序執行而不中斷,以研究死結等問題。 如需詳細資訊,請參閱 斷點動作和追蹤點。
偵錯具有使用者介面的多線程應用程式可能特別困難。 您可能會考慮在第二部計算機上執行應用程式,並使用遠端偵錯。 如需詳細資訊,請參閱 遠端偵錯。
下表顯示可用資訊,以及您可以在下列每個位置執行的動作:
| 使用者介面 | 可用資訊 | 您可以執行的動作 |
|---|---|---|
| 附加至 [處理] 對話框 | 您可以附加至的可用行程: - 行程名稱 (.exe) - 行程識別碼 - 功能表列標題 - 類型 (Managed v4.0;受控 v2.0、v1.1、v1.0;x86;x64;IA64) - 使用者名稱(帳戶名稱) - 工作階段編號 |
選取要附加至的程式 選取遠端電腦 變更連線到遠端電腦的傳輸類型 |
| 進程 視窗 | 附加的行程: - 行程名稱 - 行程識別碼 - 處理 .exe 的路徑 - 功能表列標題 - 狀態 (中斷。執行中) - 偵錯 (原生、受控等等。 - 傳輸類型 (預設值,沒有驗證的原生) - 傳輸限定元 (遠端電腦) |
工具: -附加 -分離 -終止 快捷選單: -附加 -分離 - 偵錯停止時中斷連結 -終止 |
| 偵錯位置 工具列 | - 目前進程 - 暫停應用程式 - 繼續應用程式 - 暫停和關閉應用程式 - 目前線程 - 切換目前的線程旗標狀態 - 僅顯示已標幟的線程 - 僅顯示目前的進程 - 目前的堆疊框架 |
- 切換至另一個進程 - 暫停、繼續或關閉應用程式 - 切換至目前進程中的另一個線程 - 切換至目前線程中的另一個堆疊框架 - 標幟或取消旗標目前的線程 - 僅顯示已標幟的線程 - 只顯示目前的進程 |
| 平行堆疊 視窗 | - 在一個視窗中呼叫多個線程的堆疊。 - 每個線程的作用中堆疊框架。 - 任何方法的呼叫端和被呼叫者。 - 死結偵測 |
- 篩選出指定的線程 - 篩選出外部程式代碼堆疊 - 切換至 [工作] 檢視 - 為線程加上旗標或取消標記 -縮放 - 複製堆疊框架 - 將所有堆疊儲存/匯出為映射 |
| 平行監看 式視窗 | - 旗標數據行,您可以在其中標記您想要特別注意的線程。 - 框架欄,其中箭號表示選取的框架。 - 可設定的數據行,可顯示計算機、進程、磚、工作和線程。 |
- 為線程加上旗標或取消標記 - 只顯示標示的線程 - 切換框架 - 排序數據行 - 群組線程 - 凍結或解除凍結線程 - 在 [平行監看式] 視窗中匯出數據 |
| 線程 視窗 | 目前行程中的線程: - 線程標識碼 - 受控標識碼 - 類別(主要線程、介面線程、遠端過程調用處理程式或背景工作線程) - 線程名稱 - 建立線程的位置 -優先權 - 親和性遮罩 - 暫停計數 - 行程名稱 - 旗標指標 - 暫止指標 |
工具: -搜索 - 搜尋呼叫堆疊 - 標幟 Just My Code - 將自定義模組選取專案加上旗標 - 分組依據 -列 - 展開/折疊呼叫堆疊 - 展開/折迭群組 - 凍結/解除凍結線程 快捷選單: - 在來源中顯示線程 - 切換至線程 - 凍結執行中的線程 - 解凍凍結的線程 - 為線程加上旗標以進行其他研究 - 取消將線程取消旗標 - 重新命名線程 - 顯示和隱藏線程 其他動作: - 檢視 DataTip 中線程的呼叫堆疊 |
| 來源視窗 | 左側排水溝中的線程指標表示單一或多個線程(預設為關閉,使用 [線程] 視窗中的快捷方式功能表開啟) | 快捷選單: - 切換至線程 - 為線程加上旗標以進行其他研究 - 取消將線程取消旗標 |
| [工作] 視窗 | - 檢視對象的相關信息 Task ,包括工作標識符、工作狀態(已排程、執行中、等候中、死結),以及指派給工作的線程。 - 呼叫堆疊中的目前位置。 - 委派在建立時傳遞至工作 |
- 切換至目前的工作 - 為工作加上旗標或取消標記 - 凍結或解除凍結工作 |
| GPU 線程 視窗 | - 旗標數據行,您可以在其中標記您想要特別注意的線程。 - 目前線程數據行,其中黃色箭號表示目前的線程。 - [ 線程計數 ] 數據行,其會顯示位於相同位置的線程數目。 - Line 數據行,其會顯示每個線程群組所在的程式代碼行。 - [位址 ] 數據行,其中顯示每個線程群組所在的指令位址。 - [位置] 資料行,這是地址程序代碼中的位置。 - [狀態] 資料行,顯示線程為使用中或已封鎖。 - [磚 ] 數據行,其中顯示數據列中線程的磚索引。 |
- 變更為不同的線程 - 顯示特定的磚和線程 - 顯示或隱藏資料列 - 依數據行排序 - 群組線程 - 凍結或解除凍結線程 - 為線程加上旗標或取消標記 - 只顯示標示的線程 |