python - 一组 Popen 对象上的 wait()

标签 python subprocess

我有许多 Popen 对象,每个对象代表我已启动的一个长时间运行的命令。事实上,我不希望这些命令退出。如果其中任何一个确实退出,我想等待几秒钟,然后重新启动。有没有一种好的、Pythonic 的方法来做到这一点?

例如:

import random
from subprocess import Popen

procs = list()
for i in range(10):
    procs.append(Popen(["/bin/sleep", str(random.randrange(5,10))]))

一个简单的方法可能是:

for p in procs:
    p.wait()
    print "a process has exited"
    # restart code
print "all done!"

但这不会提醒我第一个进程已退出。所以我可以尝试

for p in procs:
    p.poll()
    if p.returncode is not None:
        print "a process has exited"
        procs.remove(p)
        # restart code
print "all done!"

但是,这是一个紧密循环,会消耗 CPU。我想我可以在循环中添加一个 time.sleep(1) ,这样它就不会忙于等待,但我会失去精度。

我觉得应该有一些好方法来等待一组 pid——我说得对吗?

最佳答案

  1. “重新启动崩溃的服务器”任务确实很常见,除非有具体原因,否则可能不应该由自定义代码处理。请参阅 upstartsystemd 以及 monit

  2. multiprocessing.Pool 对象听起来像是一个胜利——它会自动启动进程,甚至在需要时重新启动它们。不幸的是它不是很可配置。

这是一个使用旧的 Popen 的解决方案:

import random, time
from subprocess import Popen


def work_diligently():
    cmd = ["/bin/sleep", str(random.randrange(2,4))]
    proc = Popen(cmd)
    print '\t{}\t{}'.format(proc.pid, cmd) # pylint: disable=E1101
    return proc


def spawn(num):
    return [ work_diligently() for _ in xrange(num) ]


NUM_PROCS = 3
procs = spawn(NUM_PROCS)
while True:
    print time.ctime(), 'scan'
    procs = [ 
        proc for proc in procs
        if proc.poll() is None
    ]
    num_exited = NUM_PROCS - len(procs)
    if num_exited:
        print 'Uhoh! Restarting {} procs'.format(num_exited)
        procs.extend( spawn(num_exited) )
    time.sleep(1)

输出:

    2340    ['/bin/sleep', '2']
    2341    ['/bin/sleep', '2']
    2342    ['/bin/sleep', '3']
Mon Jun  2 18:01:42 2014 scan
Mon Jun  2 18:01:43 2014 scan
Mon Jun  2 18:01:44 2014 scan
Uhoh! Restarting 2 procs
    2343    ['/bin/sleep', '3']
    2344    ['/bin/sleep', '2']
Mon Jun  2 18:01:45 2014 scan
Uhoh! Restarting 1 procs
    2345    ['/bin/sleep', '2']
Mon Jun  2 18:01:46 2014 scan
Uhoh! Restarting 1 procs
    2346    ['/bin/sleep', '2']
Mon Jun  2 18:01:47 2014 scan
Uhoh! Restarting 2 procs
    2347    ['/bin/sleep', '3']
    2349    ['/bin/sleep', '2']

关于python - 一组 Popen 对象上的 wait(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24002551/

相关文章:

Python 卡在 pipe.stdin.write(image.tostring())

python - 获取二叉搜索树的高度

python - 两个 numpy 数组中所有行的组合

python - 在 python 中读取/压缩一个大文件的更简洁的方法

python - 难以通过 python 使用 qhull 管道

python - 子进程超时失败

python - 如何根据分组值将字典插入数据框的行?

python - 如何在视频上n秒后运行特定代码

python - numpy 二维矩阵乘法

Python 子进程抛出 [Errno 2] 没有这样的文件或目录,只有在远程主机上时才会产生错误