我可以将文件传递给Popen并仍然以异步方式运行

时间:2016-10-03 21:12:24

标签: python asynchronous subprocess

我有一个基于Django的服务器,我正在调用一个执行大量工作的脚本。这需要是异步的,所以我正在使用Popen。但是对于调试我想将stdout和stderr从PIPE重定向到文件。这会影响异步性能吗?

如果python脚本本身已经完成(并且已经进行了回调,我应该如何确保文件正确打开和关闭。)

2 个答案:

答案 0 :(得分:1)

默认情况下,

Popen以异步方式运行。

以后可以存储和查询Popen对象。

p = subproccess.Popen(executable)

# continue with other work

p.poll() # returns None if p is still running, returncode otherwise
p.terminate() # closes the process forcefully

p.wait() # freezes the execution until process finishes - makes it synchronous

所需要的只是将p存储在某处,直到必须检查其状态,例如如果没有更好的地方,请在已启动流程的全局列表中。

<强>更新

问题似乎是如何打开文件,将其提供给Popen,然后在完成该过程时关闭文件,而不保留任何引用。

这可以通过线程完成:

def run_process(executable, filename):
    with open(filename, 'w') as f:
        subprocess.Popen(executable, stdout=f).wait()

Thread(target=run_process, args=(executable, filename)).start()

运行它并忘记它。 run_process将冻结,直到进程完成,然后它将关闭文件,但这一切都发生在不同的线程中。

注意:如果在django进程完成后线程或进程没有完成,您可能会也可能不会关心线程或进程会发生什么。

为了处理它,你可能会创建一个更复杂的线程,你会记得并在django退出之前停止;它也可以关闭该过程或等待它完成......

答案 1 :(得分:1)

这取决于您的程序需要异步的程度。写入stdout转到操作系统的文件缓存,该文件缓存通常很快,但可能会不时等待数据刷新到磁盘。通常这不是问题。

由于stdout不是控制台,它会执行缓冲写入,如果程序遇到跳过管道冲洗的非标准错误,则可能会出现问题。缓冲还可以延迟文件中的内容,例如,对文件的外部程序猫可能不会立即看到日志。

父进程应在启动子进程后关闭其文件视图,操作系统将在进程终止时关闭文件。

with open('stdout', 'w') as out, open('stderr', 'w') as err:
    proc = subprocess.Popen(['myprog'], stdout=out, stderr=err)