如何避免僵尸进程特使。连接?

2024-05-23 18:09:00 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚刚发现了“特使”模块,一个由请求创建者为python子进程编写的包装器。在

我对“connect”函数有一个问题:每次我使用它,它都会导致一个僵尸进程,我无法获得状态代码或结果。在

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

如果我做一个'ps-ef | grep thepid',我会得到一个“失效”的pid。在

我可以通过做一个操作系统。等等()或c_进程。等等(),但我无法获取命令的结果(stdout)。。。在

有什么想法吗?在


Tags: 模块函数代码none进程状态statusconnect
2条回答

在您的例子中,您应该使用run()方法

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

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

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

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

^{pr2}$

but I can't get the result (stdout) of my command...

^{}(由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)

不管最初的顺序如何,孩子睡得越少,其结果就越快提供给父母。在

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

相关问题 更多 >