【问题标题】:How to terminate a thread in Python without loop in run method?如何在运行方法中没有循环的情况下终止 Python 中的线程?
【发布时间】:2012-12-03 11:26:31
【问题描述】:

有一个方法很长的类。
为该方法创建一个线程。
我怎样才能杀死\终止这个线程?
主要问题是我无法在线程 run() 方法中检查 threading.Event,因为它不包含循环。
与此处类似的代码:

import time
import threading

class LongAction:
    def time_consuming_action(self):
        tmax = 600
        for i in range(tmax):
            print i
            time.sleep(1)
        time.sleep(tmax)
        self.tmax = tmax
        return "Slept well"

class LongActionThread(threading.Thread):
    def __init__(self, la_object):
        self.la = la_object
        threading.Thread.__init__(self)

    def run(self):
        self.la.time_consuming_action()


la = LongAction()
la_thread = LongActionThread(la)
la_thread.start()

# After 5 sec i've changed my mind and trying to kill LongActionThread
time.sleep(5)
print "Trying to kill LongActionThread"
la_thread.kill()

【问题讨论】:

  • 杀死一个线程通常不是一个好主意:stackoverflow.com/questions/323972/…
  • 我明白,但我需要。阅读此链接,但第一个示例没有帮助。我想只有一种方法 - 除了例外?
  • 如果您可能需要终止一个任务,那么在进程中运行它比在线程中运行要好得多。例如,参见multiprocessing 模块。
  • 你在 Python 中的 time_sumption_action 是真实的吗?它是否包含一个可以插入事件检查的循环?
  • time_sourcing_action 是在 Python 中,但我无法更改它。

标签: python multithreading kill


【解决方案1】:

此代码运行良好,但需要从标准输出中显式刷新数据。
尚未找到无需冲洗即可打印的方法。

import time
from multiprocessing.process import Process
import sys

class LongAction:
    def time_consuming_action(self):
        tmax = 600
        for i in range(tmax):
            print i
            time.sleep(1)
            sys.stdout.flush()
        time.sleep(tmax)
        self.tmax = tmax
        return "Slept well"
        sys.stdout.flush()

class LongActionThread(Process):
    def __init__(self, la_object):
        self.la = la_object
        Process.__init__(self)

    def run(self):
        self.la.time_consuming_action()

if __name__ == "__main__":
    la = LongAction()
    la_thread = LongActionThread(la)
    la_thread.start()

    # After 5 sec i've changed my mind and trying to kill LongActionThread
    time.sleep(5)
    print "Trying to kill LongActionThread"
    la_thread.terminate()

【讨论】:

  • OP 说 time_consuming_action() 无法更改。
【解决方案2】:

虽然杀死线程不是一个好主意,但如果你真的必须这样做,最简单的解决方案是实现一个正在运行的信号量,将你的耗时方法分成 sub_methods 并检查子方法之间的线程状态。

代码部分复制自this SO question:

class StoppableThread(threading.Thread):
    """Thread class with a stop() method. The thread itself has to check
    regularly for the stopped() condition."""

    def __init__(self,la_object):
        super(StoppableThread, self).__init__()
        self.la = la_object
        self._stop = threading.Event()

    def stop(self):
        self._stop.set()

    def stopped(self):
        return self._stop.isSet()

    def run(self):
       self.la.time_consuming_action( self.stopped )

    class La :

      def __init__(self):
      #init here

      def time_consuming_action(self, thread_stop_callback ):

          sub_work1()

          if thread_stop_callback():
             raise 'Thread Killed ! '

          sub_work2()

          if thread_stop_callback():
             raise 'Thread Killed ! '

          sub_work3()

          #etc...

【讨论】:

  • 问题是我不能改变 LongAction
猜你喜欢
  • 1970-01-01
  • 2014-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多