是否有可能终止一个正在运行的线程而不设置/检查任何标志/信号/等等?


当前回答

多处理。进程可以p.terminate()

如果我想杀死一个线程,但不想使用标志/锁/信号/信号量/事件/任何东西,我就把线程提升到完整的进程。对于只使用几个线程的代码,开销并没有那么糟糕。

例如,这可以方便地终止执行阻塞I/O的助手“线程”

转换很简单:在相关代码中替换所有线程。多线程线程。进程和所有队列。多处理队列。排队并将p.t terminate()所需的调用添加到想要杀死子进程p的父进程中

关于多处理,请参阅Python文档。

例子:

import multiprocessing
proc = multiprocessing.Process(target=your_proc_function, args=())
proc.start()
# Terminate the process
proc.terminate()  # sends a SIGTERM

其他回答

这似乎与windows 7上的pywin32一起工作

my_thread = threading.Thread()
my_thread.start()
my_thread._Thread__stop()

您可以在进程中执行命令,然后使用进程id终止它。 我需要在两个线程之间同步,其中一个线程本身不返回。

processIds = []

def executeRecord(command):
    print(command)

    process = subprocess.Popen(command, stdout=subprocess.PIPE)
    processIds.append(process.pid)
    print(processIds[0])

    #Command that doesn't return by itself
    process.stdout.read().decode("utf-8")
    return;


def recordThread(command, timeOut):

    thread = Thread(target=executeRecord, args=(command,))
    thread.start()
    thread.join(timeOut)

    os.kill(processIds.pop(), signal.SIGINT)

    return;

我对这个游戏已经很晚了,但我一直在与一个类似的问题作斗争,下面的内容似乎为我完美地解决了这个问题,并且让我在守护子线程退出时做一些基本的线程状态检查和清理:

import threading
import time
import atexit

def do_work():

  i = 0
  @atexit.register
  def goodbye():
    print ("'CLEANLY' kill sub-thread with value: %s [THREAD: %s]" %
           (i, threading.currentThread().ident))

  while True:
    print i
    i += 1
    time.sleep(1)

t = threading.Thread(target=do_work)
t.daemon = True
t.start()

def after_timeout():
  print "KILL MAIN THREAD: %s" % threading.currentThread().ident
  raise SystemExit

threading.Timer(2, after_timeout).start()

收益率:

0
1
KILL MAIN THREAD: 140013208254208
'CLEANLY' kill sub-thread with value: 2 [THREAD: 140013674317568]

在Python中,你不能直接杀死一个线程。

如果你不是真的需要Thread(!),你可以做的,而不是使用threading包,是使用 多处理包。在这里,要终止一个进程,你可以简单地调用方法:

yourProcess.terminate()  # kill the process!

Python将终止您的进程(在Unix上通过SIGTERM信号,而在Windows上通过TerminateProcess()调用)。注意在使用队列或管道时使用它!(可能会破坏队列/管道中的数据)

注意,多处理。事件和多处理。信号量的工作方式与线程完全相同。事件和线程。信号量分别。事实上,前者是后者的克隆。

如果你真的需要使用一个线程,没有办法直接杀死它。但是,您可以使用“守护线程”。事实上,在Python中,线程可以被标记为守护进程:

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

当没有活动的非守护进程线程时,主程序将退出。换句话说,当主线程(当然是非守护线程)完成其操作时,即使仍有一些守护线程在工作,程序也将退出。

注意,在调用start()方法之前,有必要将线程设置为守护进程!

当然,你可以,也应该在多进程中使用daemon。在这里,当主进程退出时,它将尝试终止其所有守护子进程。

最后,请注意sys.exit()和os.kill()不是选项。

这是基于thread2—可杀死线程ActiveState配方。

您需要调用PyThreadState_SetAsyncExc(),它只能通过ctypes模块使用。

这只在Python 2.7.3上进行了测试,但它很可能与最近的其他2一起工作。x版本。PyThreadState_SetAsyncExc()仍然存在于Python 3中以实现向后兼容性(但我还没有测试它)。

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")