程序有并发错误?NO WAY!
什么是并發錯誤
并發是指程序能夠交替執行不同的任務,以達到"同時執行效果",加快程序的運行效率。
但是并發也會導致一系列問題,以變量+1賦值為例,由于操作實際由多條指令組成,不同任務執行指令的順序可能是交錯的,所以就可能出現執行結果與我們預期結果不符合的情況。
并發錯誤很難捕獲。這是因為觸發并發錯誤需要線程以特定的順序并行執行指令,以使程序顯示錯誤行為。此外,觸發并發錯誤具有不確定性。即使在觸發并發錯誤之后,由于非確定性,將其重現并調試也可能很困難。
如果您是.NET開發者,可以嘗試使用Coyote來自動檢測并發錯誤。
Coyote
Coyote是由微軟研究院提供的一個.NET庫,旨在幫助確保您的代碼沒有并發錯誤。
Coyote的核心是一個調度器,它在測試期間控制(通過二進制重寫)程序的執行,并且能夠系統地研究并發性和不確定性,以發現安全性和活躍性缺陷。
更為重要的是,一旦Coyote發現一個錯誤,一旦 Coyote 發現了一個錯誤,它就可以讓您根據需要多次完全重現它,從而使調試和修復問題變得更加容易。
你可以運行下面的命令安裝Coyote:
dotnet?tool?install?--global?Microsoft.Coyote.CLI下面我們用官方示例程序https://github.com/microsoft/coyote-samples來體驗一下Coyote的強大功能。
定位錯誤
首先,clone下代碼后,運行下列命令進行編譯示例程序代碼:
powershell?-f?build.ps1運行下列命令進行錯誤檢查:
cd?bin\net5.0\coyote?rewrite?BoundedBuffer.dllcoyote?test?BoundedBuffer.dll?-m?TestBoundedBufferMinimalDeadlock?--iterations?100測試完成后,將會提示發現錯誤,如下圖:?
您將得到一個解釋所有這些的日志文件:
<ErrorLog>?Deadlock?detected.?Task(0)?is?waiting?for?a?task?to?complete,? but?no?other?controlled?tasks?are?enabled.? Task(1),?Task(2)?and?Task(3)?are?waiting?to?acquire?a?resource?that?is?already?acquired,? but?no?other?controlled?tasks?are?enabled. <StackTrace>????at?Microsoft.Coyote.Tasks.SynchronizedBlock.Mock.Wait()at?BoundedBufferExample.BoundedBuffer.Take()解決問題
通過錯誤日志的StackTrace,定位到出錯代碼:
while?(this.Occupied?==?0) {Monitor.Wait(this.SyncObject); }然后看看釋放SyncObject的代碼:
?Monitor.Pulse(this.SyncObject);根據錯誤日志的ErrorLog,并對照官方文檔的解釋,只需要把Pulse替換成PulseAll即可解決問題:
結論
通過上面的示例,我們可以看到,未對代碼做任何修改,就可以實現并發錯誤檢測。
如果您對項目中的多線程代碼不太放心,可以嘗試使用Coyote來幫助檢測,避免上線出現并發錯誤的可能性。
如果你覺得這篇文章對你有所啟發,請關注我的個人公眾號”My IO“,記住我!
總結
以上是生活随笔為你收集整理的程序有并发错误?NO WAY!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WPF 左侧菜单样式
- 下一篇: [翻译]在GC上加入DPAD