【问题标题】:External programs are running when multiprocessing Python is closed关闭多处理 Python 时正在运行外部程序
【发布时间】:2016-07-31 15:23:43
【问题描述】:

在 Python (3.5) 中,我开始通过 multiprocessing.Pool.map + 来自 Xshell 连接的子进程运行外部可执行文件(用 C++ 编写)。但是,由于网络状况不佳,Xshell 连接中断。

再次连接后,我看到管理 Python 已消失,但 C++ 可执行文件仍在运行(看起来正确,Pool 似乎仍在控制它们。)

问题是这是否是一个错误,以及在这种情况下我应该做什么。我不能killkill -9 他们。

添加:手动删除所有sublst_file后,所有正在运行的可执行文件(cmd)都消失了。 except sub.SubprocessError as e: 部分似乎仍在工作。

我的程序的基本框架概述如下。

import subprocess as sub
import multiprocessing as mp
import itertools as it
import os
import time

def chunks(lst, chunksize=5):
    return it.zip_longest(*[iter(lst)]*chunksize)

class Work():
    def __init__(self, lst):
        self.lst = lst

    def _work(self, sublst):
       retry_times = 6
       for i in range(retry_times):
             try:
                 cmd = 'my external c++ cmd'
                 sublst_file = 'a config file generated from sublst'
                 sub.check_call([cmd, sublst_file])
                 os.remove(sublst_file)
                 return sublst # return success sublst
             except sub.SubprocessError as e:
                 if i == (retry_times-1):
                    print('\n[ERROR] %s %s failed after %d tries\n' % (cmd, sublst_file, retry_times))
                    return []
                 else:
                     print('\n[WARNNING] %dth sleeping, please waiting for restart\n' % (i+1))
                     time.sleep(1+i)

    def work(self):
        with mp.Pool(4) as pool:
            results = pool.map(self._work, chunks(self.lst, 5))
        for r in it.chain(results):
            # other work on success items
            print(r)

【问题讨论】:

  • 这不是太模糊,但我需要阅读它几次才能完全掌握您实际在做什么,添加几行代码来演示您如何启动连接可能会有所帮助在python中。
  • @TadhgMcDonald-Jensen 我已经添加了我的代码。我猜这个问题是由重试部分引起的。
  • 这不是错误,如果出现问题,您有责任进行清理。为什么你不能杀死子进程?
  • @Phillip 他们只是没有死。
  • 如果kill -9 不起作用,最可能的解释是您尝试杀死错误的进程或作为错误的用户。对于其他人,请参阅e.g. herekill() SIGTERM 处理程序中的孩子是正确的做法,应该可以工作。

标签: python subprocess multiprocessing


【解决方案1】:

multiprocessing.Pool 确实会在 terminate() 上终止其工作人员,__del__ 也会调用它,而__del__ 又会在模块卸载(退出时)时调用。

这些家伙成为孤儿的原因是subprocess.check_call spawns 没有在退出时终止。

参考文献中没有明确提到这一事实,但没有任何地方表明生成已终止。对source code 的简要回顾也让我没有任何发现。这种行为也很容易测试。

要在父级终止时进行清理,请使用Popen 接口和此答案Killing child process when parent crashes in python

【讨论】:

  • @JonathanLeffler 关于multiprocess 的部分有据可查,所以我假设您指的是关于subprocess 的第二部分。没有明确说明,但参考文档中的任何地方都没有任何迹象表明产卵已终止。对源代码的简短审查也让我没有任何发现。
猜你喜欢
  • 2014-10-17
  • 2018-04-17
  • 1970-01-01
  • 2012-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-24
  • 2018-03-28
相关资源
最近更新 更多