1

我刚刚发现了“特使”模块,它是请求创建者为 python 子进程制作的包装器。

我的“连接”功能有问题:每次我使用它时,都会导致僵尸进程,我无法获得 status_code 或结果。

c=envoy.connect("ls -al")
c.status_code == None
 True

如果我执行“ ps -ef|grep thepid ”,我会得到一个“已失效”的 pid。

我可以通过执行 os.wait() 或 c._process.wait() 来杀死僵尸,但我无法获得命令的结果(stdout)......

任何想法?

4

2 回答 2

1

但我无法得到我的命令的结果(标准输出)......

ConnectedCommand(由envoy.connect()) 返回的类型似乎还没有准备好。特别是,如果命令接收/生成足够的(取决于平台)输入/输出,则该命令可能会死锁。

除了调用c.block()也适用于活动进程;您可以删除对该命令的所有引用并用于del c收割僵尸。如果子进程没有死;在下一个子进程开始时运行清理方法之前,它们不会被收割(这取决于实现)。

如果envoy.run()能力不足以完成您的任务;你可以直接使用subprocess模块。例如,将输入传递给多个进程并收集相应的结果;你可以使用ThreadPool.communicate()方法:

#!/usr/bin/env python
from multiprocessing.pool import ThreadPool
from subprocess import Popen, PIPE

def process(child_input):
    child, input = child_input # unpack arguments
    return child.communicate(input)[0], child.returncode # get the result


# define input to be pass to subprocesses
params = b"a b c".split()

# start subprocesses (the command is just an example, use yours instead)
children = [Popen("( echo -n {0}; sleep {0}; cat )".format(len(params) - i),
                  shell=True, stdin=PIPE, stdout=PIPE)
            for i in range(len(params))]

# use threads to wait for results in parallel
pool = ThreadPool(len(params))
for output, returncode in pool.imap_unordered(process, zip(children, params)):
    if returncode == 0:
       print("Got %r" % output)

无论原始顺序如何,孩子睡得越少,父母就可以越早获得结果。

没有僵尸,如果输入/输出超过管道缓冲区,它不会死锁。

于 2013-12-04T00:12:45.730 回答
1

在您的情况下,您应该使用该run()方法

正如特使文档建议的那样:

r = envoy.run(cmd)
print r.status_code, r.std_out

但是如果您希望命令异步运行,您可以使用connect() 后跟block()

一旦block()被调用,返回码就可用。但是 block() 会阻塞你的程序,所以逻辑应该是这样。

c1=envoy.connect(cmd1)
c2=envoy.connect(cmd2)
c3=envoy.connect(cmd3)
... more staff ...
c1.block()
print c1.status_code
于 2013-12-02T14:41:39.613 回答