2010-03-04 93 views
10

測試互斥鎖實現的最佳方法的確是正確的? (有必要實現一個互斥鎖,重用不是一個可行的選擇)如何最好地測試Mutex實現?

我已經想出了最好的是有很多(N)併發線程迭代試圖訪問受保護區域(I)次,它已一個副作用(例如更新到全局),以便可以統計訪問次數和寫入次數,以確保全局更新的數量正好是(N)*(I)。

其他建議?

+1

測試互斥鎖(以及類似的構造)非常非常困難。我很想知道爲什麼你不能使用預先存在的,經過測試和證明的解決方案。 – 2010-03-04 16:30:33

+0

「因爲我的老闆告訴我」 – 2010-03-04 16:35:23

回答

3

這讓我想起這個關於FIFO semaphore test的問題。簡單地說我的回答是:

  • 即使你有一個規範,也許它沒有傳達你的意圖究竟
  • 可以證明,該算法符合規範,而不是代碼(D.高德納)
  • 測試只揭示了錯誤的存在,而不是他們的缺席(Dijkstra算法)

所以,你的主張似乎合理的最好的事情。如果您想提高信心,請使用模糊隨機化調度和輸入。

8

形式證明比測試這種事情要好。

測試會告訴你 - 只要你不是不吉利的 - 一切都會奏效。但是一個測試是一個鈍器,它可能無法執行正確的順序以導致失敗。

要測試硬件中可用的每一個可能的操作順序,以確保您的互斥鎖在任何情況下都能正常工作,這太困難了。

測試並非沒有價值;它表明你沒有犯任何明顯的編碼錯誤。

但是您確實需要更正式的代碼檢查來證明它在正確的時間執行了正確的事情,以便一個客戶端可以自動獲取正確的互斥鎖所需的鎖資源。在許多平臺中,有特別的指示來實現這一點,如果你使用其中的一種,你有一個正確的戰鬥機會。

同樣,你必須證明該版本是原子的。

7

有了像互斥體這樣的東西,我們回到了舊規則,即測試只能證明錯誤的存在,而不是缺失。一年的測試可能會告訴你不僅僅是將代碼放在檢查中,並詢問是否有人看到問題。

1

如果證明的東西不適合你,那麼去測試一個。一定要測試所有可能的用例。瞭解如何使用這個東西,誰將使用它,以及如何使用它。當你走上測試路線時,一定要對每個場景進行每次測試(數百萬,數十億,儘可能多的測試時間)。

嘗試隨機,因爲隨機性會給你最好的機會覆蓋有限數量測試中的所有場景。請務必使用將要使用的數據和可能未使用但可以使用的數據,並確保數據不會混淆鎖定。

順便說一句,除非你知道數學和形式方法很多,否則你將沒有機會真正提出證明。

4

我與其他人一樣,這是難以置信的難以證實的決定性的,我不知道該怎麼做 - 沒有幫助,我知道!

當您說實現一個互斥鎖並且重用不是一個選項時,是出於技術原因,例如您正在使用的平臺/操作系統上沒有Mutex實現或其他原因?正在封裝某種形式的操作系統級別的「鎖定」並將其稱爲您的互斥體實現選項,例如,關於windoze的criticalsection,posix條件變量?如果你可以封裝一個較低級別的操作系統鎖,那麼你獲得正確的機會要高得多。

如果您還沒有這樣做,請閱讀Herb Sutter's Effective Concurrency文章。這些東西應該有些值得你去做。

無論如何,有些事情在你的測試考慮:

  • 如果你的互斥是遞歸的(即可以在同一線程鎖定多個 次),然後確保你做一些 引用計數測試。
  • 隨着你的全局變量,你 修改它將是最好的,如果這是一個 變量,不能被寫入 原子。例如,如果您在8位平臺上爲 ,則使用16位或 32位變量,需要使用多個彙編指令來編寫。
  • 仔細檢查裝配清單。取決於硬件平臺,雖然程序集並不直接轉化爲代碼可能被優化的方式......
  • 讓別人寫不出代碼,也寫一些測試。
  • 測試作爲許多不同的機器有不同的規格,你可以(假設這是「通用」,而不是針對特定的硬件設置)

祝你好運!

+0

關於正在寫入的值的大小的好處。我的主要問題是檢查使用的處理器操作(通過編譯器內在函數訪問)的組合在理論上和邏輯上都是正確的(在算法上是正確的)並且實際上是正確的(實現編譯忠實於邏輯正確的算法) – grrussel 2010-03-05 15:08:06

相關問題