託管執行緒處理的最佳做法

2021-08-25 10:51:00 字數 1731 閱讀 8348

多執行緒程式設計需要在程式設計時倍加注意。

對於多數任務,通過將執行請求以執行緒池執行緒的方式排隊,可以降低複雜性。

本主題將**更複雜的情形,比如協調多個執行緒的工作或處理造成阻止的執行緒。

死鎖和爭用條件

多執行緒程式設計解決了吞吐量和響應性問題,但引入此功能會帶來新的問題:死鎖和爭用條件。

當兩個執行緒中的每乙個執行緒都在嘗試鎖定另外乙個執行緒已鎖定的資源時,就會發生死鎖。

其中任何乙個執行緒都不能繼續執行。

託管執行緒處理類的許多方法都提供了超時設定,可幫您檢測到死鎖。

例如,下面的**嘗試獲取對當前例項的鎖定。

如果在 300 毫秒內未能鎖定,monitor::tryenter

將返回false

爭用條件是當程式的結果取決於兩個或更多個執行緒中的哪乙個先到達某一特定**塊時出現的一種 bug。

多次執行程式將產生不同的結果,而且給定的任何一次執行的結果都不可預知。

爭用條件的乙個簡單例子是遞增乙個字段。

假定某個類有乙個私有static字段(在 visual basic 中為shared),每建立該類的乙個例項時它都遞增一次,使用的**是 objct++; (c#) 或 objct += 1 (visual basic)。

此操作要求將 objct 中的值載入到乙個暫存器中,使該值遞增,然後將其儲存到 objct 中。

在多執行緒應用程式中,乙個已載入並遞增該值的執行緒可能會被另乙個執行緒搶先,搶先的執行緒執行全部的三個步驟;當第乙個執行緒繼續執行並儲存其值時,它覆蓋 objct,但不考慮該值在它暫停執行期間已更改這一事實。

這種特殊的爭用條件通過使用 interlocked

類的方法(如 interlocked::increment

)即可輕鬆避免。

若要了解在多個執行緒間同步資料的其他技巧,請參見為多執行緒處理同步資料。

爭用條件也可能會在同步多個執行緒的活動時發生。

編寫每一行**,都必須考慮出現以下特殊情況時會發生什麼情況,這裡的特殊情況是指:乙個執行緒在執行該行**(或構成該行的任何機器指令)前,其他執行緒搶先執行了該**。

處理器數目

多執行緒程式設計技術能夠解決單處理器計算機和多處理器計算機的諸多問題,單處理器計算機大多用來執行終端使用者軟體,多處理器計算機通常用作伺服器。

多執行緒程式設計為計算機使用者提供了更好的響應能力,並且使用空閒時間處理後台任務。

如果在單處理器計算機上使用多執行緒程式設計,那麼:

多執行緒程式設計提供了更大的吞吐量。

十個處理器可以完成乙個處理器的十倍的工作量,不過,只有將任務分開並讓十個處理器同時工作才行;執行緒為劃分任務並利用額外的處理能力提供了一種方便的辦法。

如果在多處理器計算機上使用多執行緒程式設計,那麼:

靜態成員和靜態建構函式

在類的類建構函式(c# 中的 static 建構函式、visual basic 中的 shared sub new)完成執行之前,該類不會初始化。

為防止對未初始化的型別執行**,在類建構函式完成執行之前,公共語言執行時會禁止從其他執行緒到類的 static 成員(visual basic 中的 shared 成員)的所有呼叫。

例如,如果某個類建構函式啟動了乙個新執行緒,並且該執行緒過程呼叫了該類的 static 成員,則在該類建構函式完成之前,會一直禁止新執行緒。

以上情況適用於可擁有 static 建構函式的任意型別。

一般性建議

使用多執行緒時要考慮以下準則:

託管執行緒處理的最佳做法

多執行緒程式設計需要在程式設計時倍加注意。對於多數任務,通過將執行請求以執行緒池執行緒的方式排隊,可以降低複雜性。本主題將 更複雜的情形,比如協調多個執行緒的工作或處理造成阻止的執行緒。多執行緒程式設計解決了吞吐量和響應性問題,但引入此功能會帶來新的問題 死鎖和爭用條件。當兩個執行緒中的每乙個執行緒...

C 中 託管執行緒的狀態

試著畫了乙個狀態圖,不一定對 乙個執行緒至少總是處於 threadstate 列舉中的乙個可能狀態,並且可以同時處於多個狀態。進入託管環境的非託管執行緒已處於已啟動狀態。執行緒在啟動狀態後,許多操作都可使執行緒更改狀態。下表列出使狀態發生更改的操作以及相應的新狀態。操作 由於 running 狀態的...

異常的最佳做法

設計良好的應用處理異常和錯誤以防止應用崩潰。本文描述處理和建立異常的最佳做法。處理異常 建立和引發異常 以下列表包含建立自己的異常和引發異常時應遵循的準則。在每個異常中都包含乙個本地化描述字串。使用者看到的錯誤訊息派生自引發的異常的描述字串,而不是派生自異常類。通過程式設計方式使用正確的錯誤訊息 包...