我是靠谱客的博主 明亮未来,最近开发中收集的这篇文章主要介绍python subprocess.Popen read阻塞问题解决python subprocess.Popen read阻塞问题解决,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

python subprocess.Popen read阻塞问题解决

背景

使用subprocess.Popen打开一个子进程,指定子进程的标准输入,标准输出为subprocess.PIPE,使用stdout.read()读取子进程的标准输出,当子进程没有输出时read会导致程序阻塞。

原因分析

指定标准输入,标准输出,标准错误为subprocess.PIPE后,实则是使用匿名管道和子进程进行通信。匿名管道有两个非常重要的特性:
1.当写端一直写,而读端不去读,管道被写满后,写端继续写就会阻塞;
2.当写端打开不写数据,管道为空时,读端去读就会阻塞。
我们遇到的问题就是由上面第二个原因造成的。

解决思路

  1. 使用Popen.communicate()
    在python的官方文档中提到为了避免管道缓冲被填满导致阻塞,可以使用Popen.communicate()来规避,并且可以传入timeout参数。
    缺点:communicate()后便会关闭输入管道,无法和子进程继续交互,并且不是实时获取子进程输出。
  2. 使用非阻塞方式进行读取
    网上查阅一番资料后,看到的使用非阻塞方式读取只在linux下有效。
  3. 从匿名管道本身入手
    查看了windows关于匿名管道的api后发现了PeekNamedPipe()这个函数
    使用该函数可以查看管道中是否有数据,当存在数据时再去进行读取,就可以避免由于管道没有数据造成的阻塞。
    PeekNamedPipe函数说明
    最终,步骤如下:
# 使用CreatePipe创建爱你匿名管道
# 
import _winapi
import os
import subprocess
import time

SIZE = 128

# 创建匿名管道
...
...
# 使管道可以被子进程继承
...
...
# 使用管道描述符创建startupinfo
...
...
# 开启subprocess进程,使用PeekNamedPipe、ReadFile、GetOverlappedResult获取数据
...
...

最后

以上就是明亮未来为你收集整理的python subprocess.Popen read阻塞问题解决python subprocess.Popen read阻塞问题解决的全部内容,希望文章能够帮你解决python subprocess.Popen read阻塞问题解决python subprocess.Popen read阻塞问题解决所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部