【发布时间】:2016-10-03 21:12:24
【问题描述】:
我有一个基于 Django 的服务器,我正在调用一个执行大量工作的脚本。这需要是异步的,所以我使用 Popen。但是,为了调试,我想将 stdout 和 stderr 从 PIPE 重定向到文件。这会影响异步性能吗?
当python脚本本身已经完成(并且已经进行了返回调用)时,我应该如何确保文件正确打开和关闭。
【问题讨论】:
标签: python asynchronous subprocess
我有一个基于 Django 的服务器,我正在调用一个执行大量工作的脚本。这需要是异步的,所以我使用 Popen。但是,为了调试,我想将 stdout 和 stderr 从 PIPE 重定向到文件。这会影响异步性能吗?
当python脚本本身已经完成(并且已经进行了返回调用)时,我应该如何确保文件正确打开和关闭。
【问题讨论】:
标签: python asynchronous subprocess
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 退出之前你会记住并停止它;它也可能关闭进程或等待它完成......
【讨论】:
with open(...))。另一方面,您应该保留文件引用,以便稍后关闭它。
daemon 标志是False(默认值),则在所有这些线程完成之前,主线程不会退出。这可能正是你想要的,我不知道。
这取决于您的程序需要的异步程度。对标准输出的写入会进入操作系统的文件缓存,这通常很快,但在数据刷新到磁盘时可能会不时等待。通常这不是问题。
由于 stdout 不是控制台,它会进行缓冲写入,如果程序遇到跳过刷新管道的非标准错误,这可能会成为问题。缓冲还可以延迟文件中的内容,例如,处理文件的外部程序可能不会立即看到日志。
父进程应在启动子进程后关闭文件视图,操作系统将在进程终止时关闭文件。
with open('stdout', 'w') as out, open('stderr', 'w') as err:
proc = subprocess.Popen(['myprog'], stdout=out, stderr=err)
【讨论】:
with 根本不会阻止python脚本的执行?
with 块末尾调用的file.close() 不应该影响文件吗?