【问题标题】:How can I kill a thread in python [duplicate]如何在python中杀死一个线程[重复]
【发布时间】:2012-07-11 00:15:57
【问题描述】:

我使用以下代码启动一个线程。

t = thread.start_new_thread(myfunction)

如何从另一个线程中终止线程 t。所以基本上就代码而言,我希望能够做这样的事情。

t.kill()

请注意,我使用的是 Python 2.4。

【问题讨论】:

  • 请问您为什么使用低级 thread 模块而不是高级 threading 库?

标签: python multithreading


【解决方案1】:

你不能从另一个线程中杀死一个线程。您需要向另一个线程发出信号,表明它应该结束。而“信号”并不是指使用signal函数,我的意思是你必须安排线程之间的一些通信。

【讨论】:

  • 重点是我要杀死的线程可能在一个函数中很忙,如果它变得太忙(挂起,停滞)我想突然结束它。
  • 制作线程不会挂起/停滞不前更好吗?通常你会使用某种互斥量/信号量/标志来向线程发出信号并使其脱离循环。
  • 对线程使用超时,以及捕获该超时中断的信号处理程序。
  • 对计时器对象的引用...允许您设置时间,当计时器触发时,它会调用您设置的任何函数。在这种情况下,它可能会杀死线程。 docs.python.org/release/2.4.2/lib/timer-objects.html
【解决方案2】:

如果您的线程正忙于执行 Python 代码,那么您遇到的问题比无法杀死它更大。 GIL 将阻止任何其他线程甚至运行您将用于执行杀戮的任何指令。(经过一番研究,我了解到解释器会定期释放 GIL,因此前面的语句是虚假的。然而,剩下的评论仍然存在。)

您的主题必须以合作的方式编写。也就是说,它必须定期检查信号量等信号对象,主线程可以使用信号量来指示工作线程自愿退出。

while not sema.acquire(False):
    # Do a small portion of work…

或:

for item in work:
    # Keep working…
        # Somewhere deep in the bowels…
        if sema.acquire(False):
            thread.exit()

【讨论】:

  • 如何获得sema
  • 我的线程正在等待 raw_input().... :S
  • @ntg 您需要进行非阻塞读取。在 Unix 上,您可以在标准输入和 os.pipe() 上选择()。要杀死等待的线程,只需关闭管道。这将唤醒线程,表明管道已准备就绪,并且线程可以简单地退出。
【解决方案3】:

在 Python 中,您根本无法杀死线程。

如果您真的不需要线程 (!),您可以使用 multiprocessing 包 (http://docs.python.org/2/library/multiprocessing.html)。在这里,要杀死一个进程,您可以简单地调用该方法:

yourProcess.terminate()  # kill the process!

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

注意 multiprocessing.Eventmultiprocessing.Semaphore 的工作方式与 threading.Event 完全相同>threading.Semaphore。事实上,第一个是后者的克隆。

如果你真的需要使用线程,没有办法直接杀死你的线程。但是,您可以做的是使用“守护线程”。事实上,在 Python 中,可以将 Thread 标记为 daemon

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

当没有活着的非守护线程时,主程序将退出。换句话说,当你的主线程(当然是一个非守护线程)完成它的操作时,即使还有一些守护线程在工作,程序也会退出。

注意,在调用start()方法之前,需要设置一个Thread为daemon

当然,您可以而且应该使用 daemon,即使使用 multiprocessing。在这里,当主进程退出时,它会尝试终止其所有守护子进程。

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-29
  • 2011-06-28
  • 1970-01-01
  • 1970-01-01
  • 2021-01-23
  • 1970-01-01
相关资源
最近更新 更多