有什麼辦法能夠殺死線程嗎?

是否能夠在不設置/檢查任何標誌/信號燈/等的狀況下終止正在運行的線程? html


#1樓

在Python中,您根本沒法直接殺死線程。 python

若是您實際上並不須要Thread(!),則可使用multiprocessing軟件包 ,而不是使用threading軟件包 ,這是能夠作的。 在這裏,要殺死一個進程,您能夠簡單地調用方法: 數據庫

yourProcess.terminate()  # kill the process!

Python將殺死您的進程(在Unix上經過SIGTERM信號,而在Windows上經過TerminateProcess()調用)。 在使用隊列或管道時,請注意使用它! (它可能會損壞隊列/管道中的數據) api

請注意, multiprocessing.Eventmultiprocessing.Semaphore分別以與threading.Eventthreading.Semaphore徹底相同的方式工做。 實際上,第一個是後者的克隆。 async

若是您確實須要使用線程,則沒法直接殺死它。 可是,您可使用「守護程序線程」 。 實際上,在Python中,能夠將Thread標記爲守護程序ide

yourThread.daemon = True  # set the Thread as a "daemon thread"

當沒有活動的非守護線程時,主程序將退出。 換句話說,當您的主線程(固然是非守護程序線程)完成其操做時,即便仍有一些守護程序線程在工做,程序也會退出。 測試

注意,必須在調用start()方法以前將Thread設置爲daemonspa

固然,即便有multiprocessing ,您也能夠而且應該使用daemon 。 在這裏,當主進程退出時,它將嘗試終止其全部守護進程。 線程

最後,請注意sys.exit()os.kill()不是選擇。 code


#2樓

這基於thread2-可殺死的線程(Python配方)

您須要調用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")

#3樓

from ctypes import *
pthread = cdll.LoadLibrary("libpthread-2.15.so")
pthread.pthread_cancel(c_ulong(t.ident))

t是您的Thread對象。

閱讀python源代碼( Modules/threadmodule.cPython/thread_pthread.h ),您能夠看到Thread.identpthread_t類型,所以您可使用libpthread在python中作任何pthread能夠作的事情。


#4樓

若是試圖終止整個程序,則能夠將線程設置爲「守護程序」。 參見Thread.daemon


#5樓

我想補充的一件事是,若是您在線程lib Python中閱讀了官方文檔,建議您避免使用「惡魔」線程,若是您不但願線程忽然結束,請使用Paolo Rovelli 提到的標誌。

根據官方文檔:

守護程序線程在關閉時忽然中止。 它們的資源(例如打開的文件,數據庫事務等)可能沒法正確釋放。 若是但願線程正常中止,請使其成爲非守護進程,並使用適當的信號機制,例如事件。

我認爲建立守護線程取決於您的應用程序,但總的來講(我認爲)最好避免殺死它們或使其成爲守護線程。 在多處理中,可使用is_alive()來檢查進程狀態並「終止」完成它們(還能夠避免GIL問題)。 可是,有時在Windows中執行代碼時會發現更多問題。

永遠記住,若是您有「活動線程」,Python解釋器將運行以等待它們。 (由於這個守護進程能夠幫助您,若是不要緊忽然結束)。

相關文章
相關標籤/搜索