多線程程序的測試和調試


1.首先第一步應該是先代碼審閱,在審閱多線程代碼時,重點要檢查與並發相關的錯誤。

審閱多線程代碼需要考慮的問題:

這里,列一下我的清單:

並發訪問時,那些數據需要保護?
如何確定訪問數據受到了保護?
是否會有多個線程同時訪問這段代碼?
這個線程獲取了哪個互斥量?
其他線程可能獲取哪些互斥量?
兩個線程間的操作是否有依賴關系?如何滿足這種關系?
這個線程加載的數據還是合法數據嗎?數據是否被其他線程修改過?
當假設其他線程可以對數據進行修改,這將意味着什么?並且,怎么確保這樣的事情不會發生?

可測試性設計

通常,如果代碼滿足一下幾點,就很容易進行測試:
1.每個函數和類的關系都很清楚。
2.函數短小精悍。
3.測試用例可以完全控制被測試代碼周邊的環境。
4.執行特定操作的代碼應該集中測試,而非分布式測試。
5.需要在完成編寫后,考慮如何進行測試。

最后一個因素尤為重要:即使不在寫完代碼后,去寫測試用例,這也是一個很好的建議,能讓你在寫代碼之前,想想應該怎么去測試它——用什么作為輸入,什么情況看起來會讓結果變得糟糕,以及如何激發代碼中潛在的問題,等等。

並發代碼測試的一種最好的方式:去並發化測試。如果代碼在線程間的通訊路徑上出現問,就可以讓一個已通訊的單線程進行執行,這樣會減小問題的難度。

  例如,當應用設計為一個多線程狀態機時,可以將其分為若干塊。將每個邏輯狀態分開,就能保證對於每個可能的輸入事件、轉換或其他操作的結果是正確的;這就是使用了單線程測試的技巧,測試用例提供的輸入事件將來自於其他線程。之后,核心狀態機和消息路由的代碼,就能保證時間能以正確的順序,正確的傳遞給可單獨測試的線程上,不過對於多並發線程,需要為測試專門設計簡單的邏輯狀態。或者,如果將代碼分割成多個塊(比如:讀共享數據/變換數據/更新共享數據),就能使用單線程來測試變換數據的部分。麻煩的多線程測試問題,轉換成單線程測試讀和更新共享數據,就會簡單許多。

  一件事需要小心,就是某些庫會用其內部變量存儲狀態,當多線程使用同一庫中的函數,這個狀態就會被共享。這的確是一個問題,並且這個問題不會馬上出現在訪問共享數據的代碼中。不過,隨着你對這個庫的熟悉,就會清楚這樣的情況會在什么時候出現。之后,可以適當的加一些保護和同步,或使用B計划——讓多線程安全並發訪問的功能。

構建多線程測試代碼

在特定時間內,你需要安排一系列線程,同時去執行指定的代碼段。最簡單的情況:兩個線程的情況,就很容易擴展到多個線程。

首先,你需要知道每個測試的不同之處:
1.環境布置代碼,必須首先執行
2.線程設置代碼,需要在每個線程上執行
3.線程上執行的代碼,需要有並發性
4.在並發執行結束后,后續代碼需要對代碼的狀態進行斷言檢查

最終,我們還了解了一些對測試很有幫助的工具。
以上摘抄自《C++並發編程實戰》

比如說:

1.Visual Studio提供了“線程”窗口、“GPU 線程”窗口、“並行監視”窗口和其他可簡化多線程調試的功能。 

2.Thread Checker,Thread Profiler,能以較直觀的方式發現問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM