Python3.9.6中subprocess的returncode与poll()表现差异问询
关于subprocess模块returncode与poll()的行为差异问题
在Python 3.9.6版本中,针对subprocess模块的returncode属性和poll()方法存在如下疑问:
根据官方文档:
returncode:子进程的返回码,由poll()、wait()及communicate()间接设置,None表示进程未终止。poll():检查子进程是否终止,设置并返回returncode属性,未终止则返回None。
但以下代码会陷入无限循环,若在循环中添加print(proc.poll())则正常运行:
import shlex import subprocess proc = subprocess.Popen(shlex.split('python3 --version'), stderr=subprocess.PIPE, stdout=subprocess.PIPE) while proc.returncode is None: # print(proc.poll()) print(proc.stdout.readline())
而以下代码运行正常:
import shlex import subprocess proc = subprocess.Popen(shlex.split('python3 --version'), stderr=subprocess.PIPE, stdout=subprocess.PIPE) while proc.poll() is None: # print(proc.poll()) print(proc.stdout.readline())
问题:既然proc.poll()返回proc.returncode属性,为何两者的表现会有差异?
问题解析
核心原因在于returncode属性不会主动更新,只有当调用poll()、wait()或communicate()这类方法时,才会去查询子进程状态并更新returncode的值。
第一段代码的循环条件直接判断proc.returncode is None:
- 子进程启动后,
returncode初始值是None - 循环内仅调用
stdout.readline(),没有触发任何能更新returncode的方法 - 即便子进程已经执行完毕退出,
returncode依然保持初始的None,导致循环永远不会终止
第二段代码用proc.poll() is None作为循环条件:
- 每次循环都会调用
poll()方法,该方法会主动查询子进程的当前状态 - 如果子进程已终止,
poll()会更新proc.returncode为实际返回码,同时返回该值,循环条件不成立,循环终止 - 如果子进程未终止,
poll()返回None,循环继续
而如果在第一段代码的循环中添加print(proc.poll()),相当于每次循环都主动调用了poll(),自然会更新returncode,当子进程退出后returncode不再是None,循环也就正常结束了。
内容的提问来源于stack exchange,提问作者ssayno
相关产品推荐
相关产品推荐

