python-非阻塞子进程。

我试图进行一个非阻塞子进程调用,以从我的main.py程序中运行slave.py脚本。 当这个slave.py运行一段时间然后退出后,我需要通过main.py将args从main.py传递到slave.py一次。

main.py
for insert, (list) in enumerate(list, start =1):

    sys.args = [list]
    subprocess.call(["python", "slave.py", sys.args], shell = True)


{loop through program and do more stuff..}

还有我的奴隶脚本

slave.py
print sys.args
while True:
    {do stuff with args in loop till finished}
    time.sleep(30)

当前,slave.py阻止main.py运行其余任务,我只希望slave.py在将args传递给main.py之后独立于main.py。 这两个脚本不再需要通信。

我已经在网上找到了一些关于非阻塞subprocess.call的帖子,但是大多数帖子都集中在要求与slave.py进行某些当前我不需要的通信上。 有谁知道如何以简单的方式实现这一目标?

DavidJB asked 2020-08-12T07:54:04Z
2个解决方案
42 votes

您应该使用subprocess.Popen而不是shell = True

就像是:

subprocess.Popen(["python", "slave.py"] + sys.argv[1:])

shell = True上的文档中:

运行args描述的命令。 等待命令完成,然后返回returncode属性。

(如果要使用shell = True,也不要使用列表来传递参数)。


这是一个MCVE1示例,演示了非阻塞子流程调用:

import subprocess
import time

p = subprocess.Popen(['sleep', '5'])

while p.poll() is None:
    print('Still sleeping')
    time.sleep(1)

print('Not sleeping any longer.  Exited with returncode %d' % p.returncode)

依赖于python语言的最新更改以允许基于协同例程的并行性的另一种方法是:

# python3.5 required but could be modified to work with python3.4.
import asyncio

async def do_subprocess():
    print('Subprocess sleeping')
    proc = await asyncio.create_subprocess_exec('sleep', '5')
    returncode = await proc.wait()
    print('Subprocess done sleeping.  Return code = %d' % returncode)

async def sleep_report(number):
    for i in range(number + 1):
        print('Slept for %d seconds' % i)
        await asyncio.sleep(1)

loop = asyncio.get_event_loop()

tasks = [
    asyncio.ensure_future(do_subprocess()),
    asyncio.ensure_future(sleep_report(5)),
]

loop.run_until_complete(asyncio.gather(*tasks))
loop.close()

1在OS-X上使用python2.7和python3.6测试

mgilson answered 2020-08-12T07:54:42Z
22 votes

这里有三个层次的完整性。

正如mgilson所说,如果您只是将subprocess.call换成subprocess.Popen,并保持其他所有内容不变,则main.py将不会等待slave.py完成才继续。 仅凭其本身就足够了。 如果您关心周围的僵尸进程,则应保存从subprocess.Popen返回的对象,并在以后使用其wait方法。 (当main.py退出时,僵尸会自动消失,因此,如果main.py运行很长时间和/或可能创建许多子进程,这只是一个严重的问题。)最后,如果您不想让僵尸 但您也不想决定在哪里进行等待(如果两个进程之后都运行了很长且不可预测的时间,这可能是合适的),请使用python-daemon库让从属设备将其自身与主设备解除关联-在 在这种情况下,您可以继续在主服务器中使用subprocess.call

zwol answered 2020-08-12T07:55:08Z
translate from https://stackoverflow.com:/questions/16071866/non-blocking-subprocess-call