我有一个基于Django的服务器,我正在调用一个执行大量工作的脚本。这需要是异步的,所以我正在使用Popen。但是对于调试我想将stdout和stderr从PIPE重定向到文件。这会影响异步性能吗?
如果python脚本本身已经完成(并且已经进行了回调,我应该如何确保文件正确打开和关闭。)
答案 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)