【问题标题】:Can python subprocess pipe reattach to original child process when program restart?程序重新启动时,python子进程管道可以重新附加到原始子进程吗?
【发布时间】:2014-10-11 09:41:42
【问题描述】:

我正在寻找一种安全的方式来重新启动我的 python 程序,它能够重新控制在重新启动之前启动的子进程。

我使用带有线程的子进程来监视stdout/stderr 的长期运行command,它将不断生成一些输出消息。

示例代码sn-p如下:

class PS(threading.Thread):
    def __init__(self, command):
        threading.Thread.__init__(self)
        self.command = command

    def run(self):
        try:
            process = subprocess.Popen(self.command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
            for line in iter(process.stdout.readline, ''):
                ''' do something to line'''

当我的 python 主程序终止时(例如杀死它的 pid),它的子进程(PS 类执行的command)作为后台进程仍然存在。

我的问题是,python 中有没有办法“重新附加”子进程,以便我可以继续监视它的 stdout/stderr

附:我只需要在 linux 环境下,更具体地说是在 ubuntu 14.04 中。

【问题讨论】:

  • 如果子进程在父进程退出后尝试写入其标准输出,子进程可能会死掉,因为它的标准输出是一个管道,其另一端是父进程,而不是文件。
  • @chepner 我不知道怎么做,但我确信子进程还活着。
  • 但它还在产生输出吗?即使它以某种方式缓冲,您的程序仍然可能会丢失一些输出,具体取决于重新连接所需的时间。只需写入一个文件,然后让父级从文件而不是管道中读取。
  • 我尝试了一个小例子 ("while :; do echo $i; i=$((i+1)); sleep 1; done"),但那个孩子没有在父 Python 进程退出后存活下来。
  • @chepner 以下示例import subprocess; subprocess.Popen(['python', '-c', 'while True: print("test")']) 确实在父 python 进程退出后仍然存在。

标签: python subprocess pipe reconnect


【解决方案1】:

当子级的标准输出绑定到管道时,如果子级在父级死亡后尝试写入该管道,子级将收到 SIGPIPE 信号,因为管道的远程端不再存在。

为确保子代在父代中存活下来,并允许父代恢复,您应该简单地写入文件并让父代从该文件中读取。

【讨论】:

    猜你喜欢
    • 2013-12-18
    • 2023-03-16
    • 2011-04-25
    • 1970-01-01
    • 2016-09-20
    • 1970-01-01
    • 1970-01-01
    • 2018-08-04
    • 1970-01-01
    相关资源
    最近更新 更多