我有一个shell脚本,它对传递的字符串进行一些处理,然后将其写入文件。但是,我不希望我的函数foo()等待它完成操作。如何在不等待process(msg)完成执行的情况下调用process(msg),然后继续执行{code block 2}?
def process(msg):
subprocess.call(['sh', './process.sh', msg])
def foo():
# {code block 1}
process(msg)
# {code block 2}foo()将从另一个函数调用,几乎每秒调用一到两次。
发布于 2021-09-26 17:20:22
subprocess.call()和subprocess.run()创建一个进程,等待它完成,然后返回一个CompletedProcess对象。
subprocess.Popen()创建一个进程并返回它。它是在前面函数的幕后使用的。然后,您可以等待该过程完成,向其发送消息,或者其他您想要对其执行的操作。这些参数与call或run的参数基本相同。
https://docs.python.org/3/library/subprocess.html
作为一点详细说明,Popen是使用os启动新进程的python实现。os.fork()是一个较低的级别,它实际上并不做我们想要做的事情,它会产生另一个python解释器实例,它的内存状态与当前解释器的实例相同。如果你想使用较低级别的syscall,os.spawn比os.fork更接近subprocess.run。
为了验证Popen正在做您想要做的事情,这个测试程序将发出"returncode = None",然后等待5秒,并输出"returncode = 0“
from subprocess import Popen
p = Popen(["sleep", "5"])
print("started the proc") # this will print immediately
p.poll() # this checks if the process is done but does not block
print(f"p returncode = {p.returncode}")
p.wait() # this blocks until the process exits
print(f"p returncode = {p.returncode}")发布于 2021-09-26 18:27:41
你需要的是https://docs.python.org/3/library/os.html#os.fork,也就是os.fork(),这样你就可以产生一个比父进程更长寿的子进程,这个父进程可以稍后被Linux上的systemd声明。我对Windows一无所知。
发布于 2021-10-25 19:21:10
只是为了完整性:Python提供了一个高级接口来实现这一点:https://docs.python.org/3.9/library/asyncio-subprocess.html#subprocesses
文档中的示例:
import asyncio
async def run(cmd):
proc = await asyncio.create_subprocess_shell(
cmd,
stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE)
stdout, stderr = await proc.communicate()
print(f'[{cmd!r} exited with {proc.returncode}]')
if stdout:
print(f'[stdout]\n{stdout.decode()}')
if stderr:
print(f'[stderr]\n{stderr.decode()}')
asyncio.run(run('ls /zzz'))https://stackoverflow.com/questions/69337180
复制相似问题