使用pthread_cancel()取消子線程的風險

記錄一次使用pthread_cancel取消線程導致的bug

問題背景

這邊使用了一個線程在讀寫數據庫,但基於某些事件條件下,需要頻繁的啓動和關閉這個寫數據庫的線程。然後就發現,當這個線程的啓動關閉極其頻繁時,會出現數據庫受損狀況。經過多次測試,這個問題百分百復現。而且,可以保證的是,只有這一個線程在讀寫數據庫,因此也不存在多線程操作數據庫導致數據庫受損的情況

bug定位

經過排查,最後是由於pthread_cancel()取消寫數據庫的子線程的時候,它的取消是任意一個取消點,所如果當時數據庫在執行寫操作,它佔有數據庫的寫鎖。當取消指令收到後,線程立即取消,導致寫鎖無法釋放。重啓子線程的時候,會發現數據庫仍然處於被鎖的狀態。

解決方案

設置一個取消點標識,在子線程的業務線邏輯處理完成之後,設置一個取消點。再使用pthread_cancel()取消子線程的時候,會執行到這個取消點之後再取消。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章