2010-07-15 95 views
2

我在C++中編寫了一個線程安全的(至少目標是這樣的)容器類。我在訪問成員時鎖定互斥體,並在完成時釋放。 現在,我試着編寫一個測試用例,如果它真的是線程安全的。 比方說,我有Container容器和兩個線程Thread1 Thread2。如何編寫測試用例以確保線程安全

Container container; 
Thread1() 
{ 
    //Add N items to the container 
} 
Thread2() 
{ 
    //Add N items to the container 
} 

以這種方式,它在N = 1000時沒有問題。

但我不確定這個迴歸測試是否足夠。有沒有一種確定的方法來測試這樣的類?

謝謝。

回答

7

有沒有真正的方法來編寫測試證明其安全。

您只能設計它,所以它是安全的,並測試您的設計是否實現。最好你能做的就是壓力測試。

0

這是一個合理的出發點,但我想提出幾點建議:四核機器上

  1. 運行測試,以提高真正的資源爭用的可能性。
  2. 我不建議使用固定數量的線程,而是建議隨機數量的線程,其下限等於測試機器上的處理器數量,上限是該數字的四倍。
  3. 考慮偶爾使用大量項目(比如說100,000)。
  4. 在優化版本(非調試版本)上運行測試。

如果您的目標是Windows,您可能需要考慮使用臨界區域而不是互斥體,因爲它們通常性能更高。

0

證明它的安全是不可能的,但對於提高發現錯誤的壓力測試的機會,你可以修改容器的add方法,以便看起來是這樣的:

// Assuming all this is thread safe 
if (in_use_flag == true) { 
    error! 
} 
in_use_flag = true; 

... original add method code .... 

sleep(long_time); 
in-use-flag = false; 

這樣,你幾乎可以確保兩個線程同時嘗試訪問容器,並檢查這種情況 - 從而確保線程安全性實際工作。

PS我也會刪除互斥保護,看看它一次失敗。

1

我想你寫了一個通用的容器,並且你想驗證兩個不同的線程不能在同一時間插入項目。

如果我的假設是正確的,那麼我的建議是編寫一個自定義類,讓你重載拷貝構造函數,插入一個可以被參數化的睡眠。

要測試您的容器,請爲您的自定義類創建一個實例,然後在第一個線程中插入自定義類的實例,並使用長sleep,同時啓動第二個線程以嘗試插入實例自定義類與一個簡短的sleep。如果第二次插入在第一次插入之前回來,您知道測試失敗。

+0

捕捉一些競爭條件的好方法,但它也可能隱藏其他人。有沒有保證的方式來驗證沒有競爭條件,寫幾個測試,而@Grimmy建議應該肯定是其中之一。 – jalf 2010-07-15 10:45:09