2013-09-23 61 views
2

我有一些常規運行的代碼,並且每隔一段時間(如一個月一次)程序似乎掛在某處,我不確定它在哪裏。以編程方式在多線程中退出python腳本

我以爲我會執行[事實證明是不完全]檢查程序已運行多長時間的「快速修復」。我決定使用多線程來調用函數,然後在運行時檢查時間。

例如:

import datetime 
import threading 

def myfunc(): 
    #Code goes here 

t=threading.Thread(target=myfunc) 
t.start() 
d1=datetime.datetime.utcnow() 
while threading.active_count()>1: 
    if (datetime.datetime.utcnow()-d1).total_seconds()>60: 
    print 'Exiting!' 
    raise SystemExit(0) 

然而,這不會關閉其他線程(MYFUNC)。

什麼是最好的方式去殺死其他線程?

+1

很有關係:http://stackoverflow.com/q/905189/132382 – pilcrow

+1

如果您想在'SystemExit'提高其他線程立即死亡,讓他們守護線程。 – roippi

回答

3

文檔可能會更清晰。提高SystemExit告訴解釋器退出,但「正常」退出處理仍然完成。正常退出處理的一部分是.join()-所有活動的非守護線程。但是你的流氓線程永遠不會結束,所以退出處理將永遠等待加入它。

正如@roippi說,你可以在開始之前做

t.daemon = True 

。正常退出處理不是等待守護進程線程。當主進程退出時,你的操作系統應該殺死它們。

另一種替代方法:

import os 
os._exit(13) # whatever exit code you want goes there 

即停止解釋器 「立即」,並跳過所有正常退出處理。

挑選你的毒藥;-)

+0

請注意,這打破了'atexit'回調 –

1

有沒有辦法殺死一個線程。你必須殺死目標內的目標。最好的方法是用鉤子和queue。它是這樣的。

import Threading 
from Queue import Queue 

# add a kill_hook arg to your function, kill_hook 
# is a queue used to pass messages to the main thread 
def myfunc(*args, **kwargs, kill_hook=None): 
    #Code goes here 
    # put this somewhere which is periodically checked. 
    # an ideal place to check the hook is when logging 
    try: 
    if q.get_nowait(): # or use q.get(True, 5) to wait a longer 
     print 'Exiting!' 
     raise SystemExit(0) 
    except Queue.empty: 
     pass 

q = Queue() # the queue used to pass the kill call 
t=threading.Thread(target=myfunc, args = q) 
t.start() 
d1=datetime.datetime.utcnow() 
while threading.active_count()>1:   
    if (datetime.datetime.utcnow()-d1).total_seconds()>60: 
    # if your kill criteria are met, put something in the queue 
    q.put(1) 

我本來是在網上找到這個答案的,可能是this。希望這可以幫助!

另一種解決方案是使用單獨的Python實例,並使用psutils來監視另一個Python線程,從系統級別將其殺死。

哇,我也喜歡daemon和stealth os._exit解決方案!