【问题标题】:terminate thread and child-threads终止线程和子线程
【发布时间】:2019-05-07 16:32:46
【问题描述】:

我将多个线程与子线程一起使用。现在我想停止父线程或等到父线程完成工作而不检查并停止所有子线程。 我的想法是用一个进程包装父线程,然后终止进程,这似乎终止了相应的父线程及其所有子线程。

def worker(conn):

    #this is the class including the parent thread
    xi = Test_Risk_Calc('99082')
    #start working
    xi.test()    
    #finished

    print ('EVERYTHING IS DONE, BUT CHILD THREADS ARE STILL ALIVE')
    conn.send('EXIT SEND')
    return

def main():
    parent_conn, child_conn = Pipe()
    p = multiprocessing.Process(target=worker, args=(child_conn,))
    p.start()
    #wait for finished parent-thread
    print(parent_conn.recv())
    p.terminate()
    p.join()
    print('JOINED, PROCESS AND ALL ITS THREADS ARE TERMINATED')
    return

我不确定这是否是解决问题的正确方法

【问题讨论】:

  • Python 中的线程是非常低级的,最好使用某种抽象来帮助正确处理这些事情。哪一个取决于您目前使用线程的原因

标签: python multithreading multiprocessing


【解决方案1】:

我认为你已经做到了。但是,您可以避免总是有点“硬”的“终止”。

对此的简单解决方案是使用参数“daemon = True”启动子线程。如果父线程终止,这实际上会自动终止子线程。

就像我之前说的,这可能看起来更干净一些,但我认为最终还是一样的。

编辑:

也许考虑使用 asyncio (async/await) 进行并发编程。您可以使用

创建任务
task = asyncio.create_task(my_task())

稍后取消这些任务

task.cancel()

这里的好处是,这个“取消”会向任务中抛出异常。所以在任务中你可以做这样的事情:

async def my_task():
  try:
    ... stuff ...
  except asyncio.CancelledError:
    ... you can handle the cancellation, or ignore it

在python中,任务不是很有用。对于并发执行,您可以更好地使用 asyncio,如果您有 cpu-bound 任务,您可以使用多处理(可能以进程池的形式)。

【讨论】:

  • Python 的Thread object docu:守护线程在关闭时突然停止。它们的资源(如打开的文件、数据库事务等)可能无法正常释放。如果您希望线程优雅地停止,请将它们设为非守护线程并使用合适的信号机制,例如 Event
  • 感谢您的链接。但是,是的,这就是我的意思。到头来还是和以前一样, 也只是终止而已。对我来说,将孩子声明为“deamon”只是明确声明这是所需的行为。
  • 不,OP 在 进程 上调用 terminate,而不是线程。线程没有terminate 方法。线程,如果它们是非守护线程,则由您或implicitly during interpreter shutdown 明确指定,或者在守护线程的情况下,它们仅以解释器进程结束。
  • 我不明白你的论点。我知道他在一个进程上调用终止。但是,他描述了该进程会产生子线程。我唯一要描述的是这些子线程以任何方式终止。如果父进程终止或者他使用守护线程。如果使用恶魔线程,他就不必终止父进程,因为根据他的描述,进程正常结束。因此,在他的示例中,必须调用“终止”只是因为进程仍在等待子线程。
  • Oooohhh! 要求是停止无限期运行的由另一个自行终止的线程启动的线程?我真的不明白。你当然是对的,很抱歉造成混乱。我的 cmets 会自毁,如果有疑问,将永远不存在 :D 不过,这似乎是一种不寻常的使用流程的方法。
猜你喜欢
  • 2011-02-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-07
  • 2019-01-27
  • 2011-01-16
相关资源
最近更新 更多