Python 非阻塞子进程.call

Python 非阻塞子进程.call,python,subprocess,Python,Subprocess,我正在尝试进行非阻塞子进程调用,以从main.py程序运行slave.py脚本。在这个slave.py运行一段时间后,当它(slave.py)第一次通过subprocess.call启动时,我需要将参数从main.py传递到slave.py一次,然后退出 main.py for insert, (list) in enumerate(list, start =1): sys.args = [list] subprocess.call(["python", "slave.py",

我正在尝试进行非阻塞子进程调用,以从main.py程序运行slave.py脚本。在这个slave.py运行一段时间后,当它(slave.py)第一次通过subprocess.call启动时,我需要将参数从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在向其传递参数后独立于main.py。这两个脚本不再需要通信


我在网上找到了一些关于non-blocking subprocess.call的帖子,但大多数帖子都集中在我目前不需要与slave.py通信的某个点上。有人知道如何以一种简单的方式实现这一点吗

您应该使用
subprocess.Popen
而不是
subprocess.call

比如:

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

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

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


下面是一个MCVE1示例,演示了一个非阻塞的supprocess调用:

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使用python2.7和python3.6在OS-X上进行测试这里有三个层次的彻底性

正如mgilson所说,如果您只是将
subprocess.call
换成
subprocess.Popen
,保持其他一切不变,那么main.py将不会等待slave.py完成,然后继续。这本身就足够了。如果您关心挂起,那么应该保存从
subprocess.Popen
返回的对象,并在稍后调用其
wait
方法。(当main.py退出时,僵尸将自动消失,因此,如果main.py运行很长时间和/或可能创建许多子流程,这是一个严重的问题。)最后,如果您不想要僵尸,但也不想决定在哪里等待(如果两个进程都运行了很长一段时间且无法预测,这可能是合适的),使用库使从属进程与主进程解除关联——在这种情况下,您可以继续在主进程中使用
子进程调用。

用于Python 3.8.x

import shlex
import subprocess

cmd = "<full filepath plus arguments of child process>"
cmds = shlex.split(cmd)
p = subprocess.Popen(cmds, start_new_session=True)
导入shlex
导入子流程
cmd=“”
cmds=shlex.split(cmd)
p=subprocess.Popen(cmds,start\u new\u session=True)
这将允许父进程退出,而子进程继续运行。不确定是否存在僵尸


在macOS 10.15.5上的Python3.8.1上进行了测试,这似乎是可行的,但是当我在slave.py中包含While循环时,它似乎被卡住了,并且在循环中没有执行任何操作(即使使用计时器。sleep()函数..?@mgilson:你能分享一下如何使用它的一般示例吗?我是说,当以非阻塞方式使用它时,控制流应该是什么样子。我很感激。@ViFI--当然,我添加了一个以非阻塞方式使用
Popen
的示例。有没有一种方法可以像
p1&p2&然后使用
asyncio
等待所有这些任务?我希望这不需要多处理模块。当然,您只需要一个
do_p1
函数和一个
do_p2
函数,然后将它们都添加到
任务列表中。