前言:
不要試圖用強制方法殺掉一個python線程,這從服務設計上就存在不合理性。 多線程本用來任務的協作并發,如果你使用強制手段干掉線程,那么很大幾率出現意想不到的bug。 請記住一點,鎖資源不會因為線程退出而釋放鎖資源 !
我們可以舉出兩個常見的例子:
1. 有個A線程拿到了鎖,因為他是被強制干掉的,沒能及時的release()釋放鎖資源,那么導致所有的線程獲取資源是都被阻塞下去,這就是典型的死鎖場景。
2.在常見的生產消費者的場景下,消費者從任務隊列獲取任務,但是被干掉后沒有把正在做的任務丟回隊列中,那么這就造成了數據丟失。
下面是java和python終止線程的方法:
java有三種方法可以使終止線程:
1. 使用退出標志,使線程正常退出,也就是當run方法完成后線程終止。
2. 使用stop方法強行終止線程(不推薦使用,因為stop和suspend、resume一樣,也可能發生不可預料的結果)。
3. 使用interrupt方法中斷線程。
python可以有兩種方法:
1. 退出標記
2. 使用ctypes強行殺掉線程
不管是python還是java環境下,理想的停止退出線程方法是 讓線程自個自殺,所謂的線程自殺就是 你給他一個標志位,他退出線程。
下面我們會采用多種方法來測試 停止python線程的異常情況。我們查看一個進程所有的執行線程, 進程是用過掌控資源,線程是用作調度單元,進程要被調度執行必須要有一個線程,默認的線程和進程的pid一樣的。
ps -mp 31449 -o THREAD,tid USER %CPU PRI SCNT WCHAN USER SYSTEM TIDroot 0.0 - - - - - -root 0.0 19 - poll_s - - 31449root 0.0 19 - poll_s - - 31450
獲取到了進程所有的線程后,通過strace得知 31450 是需要我們kill的線程id,當我們kill的時候,會出現整個進程都崩潰的情況。 在多線程環境下,產生的信號是傳遞給整個進程的,一般而言,所有線程都有機會收到這個信號,進程在收到信號的的線程上下文執行信號處理函數,具體是哪個線程執行的難以獲知。也就是說,信號會隨機發個該進程的一個線程。
strace -p <span style="font-size:14px;line-height:21px;">31450</span> Process <span style="font-size:14px;line-height:21px;">31450</span> attached - interrupt to quitselect(0, NULL, NULL, NULL, {0, 320326}) = 0 (Timeout)select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)select(0, NULL, NULL, NULL, {1, 0}) = 0 (Timeout)select(0, NULL, NULL, NULL, {1, 0}) = ? ERESTARTNOHAND (To be restarted)--- SIGTERM (Terminated) @ 0 (0) ---Process <span style="font-size:14px;line-height:21px;">31450</span> detached
新聞熱點
疑難解答