是否能夠在不設置/檢查任何標誌/信號燈/等的狀況下終止正在運行的線程? html
在Python中,您根本沒法直接殺死線程。 python
若是您實際上並不須要Thread(!),則可使用multiprocessing軟件包 ,而不是使用threading軟件包 ,這是能夠作的。 在這裏,要殺死一個進程,您能夠簡單地調用方法: 數據庫
yourProcess.terminate() # kill the process!
Python將殺死您的進程(在Unix上經過SIGTERM信號,而在Windows上經過TerminateProcess()
調用)。 在使用隊列或管道時,請注意使用它! (它可能會損壞隊列/管道中的數據) api
請注意, multiprocessing.Event
和multiprocessing.Semaphore
分別以與threading.Event
和threading.Semaphore
徹底相同的方式工做。 實際上,第一個是後者的克隆。 async
若是您確實須要使用線程,則沒法直接殺死它。 可是,您可使用「守護程序線程」 。 實際上,在Python中,能夠將Thread標記爲守護程序 : ide
yourThread.daemon = True # set the Thread as a "daemon thread"
當沒有活動的非守護線程時,主程序將退出。 換句話說,當您的主線程(固然是非守護程序線程)完成其操做時,即便仍有一些守護程序線程在工做,程序也會退出。 測試
注意,必須在調用start()
方法以前將Thread設置爲daemon
! spa
固然,即便有multiprocessing
,您也能夠而且應該使用daemon
。 在這裏,當主進程退出時,它將嘗試終止其全部守護進程。 線程
最後,請注意sys.exit()
和os.kill()
不是選擇。 code
您須要調用PyThreadState_SetasyncExc(),該方法僅可經過ctypes使用。
該功能僅在Python 2.7.3上進行了測試,但可能與其餘最新的2.x版本一塊兒使用。
import ctypes def terminate_thread(thread): """Terminates a python thread from another thread. :param thread: a threading.Thread instance """ if not thread.isAlive(): return exc = ctypes.py_object(SystemExit) res = ctypes.pythonapi.PyThreadState_SetAsyncExc( ctypes.c_long(thread.ident), exc) if res == 0: raise ValueError("nonexistent thread id") elif res > 1: # """if it returns a number greater than one, you're in trouble, # and you should call it again with exc=NULL to revert the effect""" ctypes.pythonapi.PyThreadState_SetAsyncExc(thread.ident, None) raise SystemError("PyThreadState_SetAsyncExc failed")
from ctypes import * pthread = cdll.LoadLibrary("libpthread-2.15.so") pthread.pthread_cancel(c_ulong(t.ident))
t是您的Thread
對象。
閱讀python源代碼( Modules/threadmodule.c
和Python/thread_pthread.h
),您能夠看到Thread.ident
是pthread_t
類型,所以您可使用libpthread
在python中作任何pthread
能夠作的事情。
若是試圖終止整個程序,則能夠將線程設置爲「守護程序」。 參見Thread.daemon
我想補充的一件事是,若是您在線程lib Python中閱讀了官方文檔,建議您避免使用「惡魔」線程,若是您不但願線程忽然結束,請使用Paolo Rovelli 提到的標誌。
根據官方文檔:
守護程序線程在關閉時忽然中止。 它們的資源(例如打開的文件,數據庫事務等)可能沒法正確釋放。 若是但願線程正常中止,請使其成爲非守護進程,並使用適當的信號機制,例如事件。
我認爲建立守護線程取決於您的應用程序,但總的來講(我認爲)最好避免殺死它們或使其成爲守護線程。 在多處理中,可使用is_alive()
來檢查進程狀態並「終止」完成它們(還能夠避免GIL問題)。 可是,有時在Windows中執行代碼時會發現更多問題。
永遠記住,若是您有「活動線程」,Python解釋器將運行以等待它們。 (由於這個守護進程能夠幫助您,若是不要緊忽然結束)。