我正在使用Python 2.7.8在Windows环境中多次协调和自动运行多个应用程序。在每次运行期间,我使用subprocess.Popen
启动多个子流程,将subprocess.PIPE
stdin
和stdout
传递给每个子流程,如下所示:
proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
其中cmd
是参数列表。
脚本等待外部触发器知道给定运行何时完成,然后通过将字符串写入每个stdin
对象的Popen
来终止当前正在运行的每个应用程序。应用程序读取此字符串,并执行自己的正常关闭(这就是我不能简单地调用kill()
或terminate()
)的原因。
# Try to shutdown process
timeout = 5
try:
if proc.poll() is None:
proc.stdin.write(cmd)
# Wait to see if proc shuts down gracefully
while timeout > 0:
if proc.poll() is not None:
break
else:
time.sleep(1)
timeout -= 1
else:
# Kill it the old fashioned way
proc.kill()
except Error:
pass # Process as necessary...
应用程序完成后,我留下了Popen
个对象。如果我检查该对象的stdin
或stdout
成员,我会得到以下内容:
<open file '<fdopen>', mode 'wb' at 0x0277C758>
然后脚本循环执行下一次运行,重新启动必要的应用程序。
我的问题是,我是否需要每次都为close()
和stdin
文件描述符显式调用stdout
,以避免泄漏,即finally
声明如上?我想知道这一点,因为在给定的脚本中循环可能会发生数百甚至数千次。
我查看了subprocess.py代码,但管道的文件句柄是由_subprocess
模块中明显的Windows(-only)调用创建的,所以我无法获得任何进一步的细节
答案 0 :(得分:2)
管道最终可能会在垃圾收集过程中关闭,但您不应该依赖它并明确关闭管道。
def kill_process(process):
if process.poll() is None: # don't send the signal unless it seems it is necessary
try:
process.kill()
except OSError: # ignore
pass
# shutdown process in `timeout` seconds
t = Timer(timeout, kill_process, [proc])
t.start()
proc.communicate(cmd)
t.cancel()
.communicate()
方法关闭管道并等待子进程退出。