Python subprocess.Popen中communicate()和wait()区别
刚开始我是使用的wait(),但是当adb命令返回太多时,程序就会卡死,查询得知原因后,才使用了communicate(),communicate()返回一个元组:(stdoutdata, stderrdata)
转自:http://blog.csdn.net/carolzhang8406/article/details/22286913
之所以会纠结到这个问题上是因为发现在调用Popen的wait方法之后程序一直没有返回。google发现wait是有可能产生死锁的。为了把这个问题彻底弄清楚,搜索一些资料过来看看:
看到别人的例子:
今天遇到的一个问题。简单说就是,使用 subprocess
模块的 Popen
调用外部程序,如果 stdout
或 stderr
参数是
pipe,并且程序输出超过操作系统的 pipe
size时,如果使用 Popen.wait()
方式等待程序结束获取返回值,会导致死锁,程序卡在 wait()
调用上。
ulimit -a
看到的 pipe size 是
4KB,那只是每页的大小,查询得知 linux 默认的 pipe
size 是 64KB。
看例子:
#!/usr/bin/env python
# coding: utf-8
# yc@2013/04/28
import subprocess
def test(size):
print 'start'
cmd = 'dd if=/dev/urandom bs=1 count=%d 2>/dev/null' % size
p = subprocess.Popen(args=cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True)
#p.communicate()
p.wait()
print 'end'
# 64KB
test(64 * 1024)
# 64KB + 1B
test(64 * 1024 + 1)
首先测试输出为 64KB 大小的情况。使用 dd 产生了正好 64KB 的标准输出,由 subprocess.Popen
调用,然后使用 wait()
等待 dd
调用结束。可以看到正确的 start
和 end
输出;然后测试比 64KB 多的情况,这种情况下只输出了 start
,也就是说程序执行卡在了 p.wait()
上,程序死锁。具体输出如下:
start
end
start
那死锁问题如何避免呢?官方文档里推荐使用 Popen.communicate()
。这个方法会把输出放在内存,而不是管道里,所以这时候上限就和内存大小有关了,一般不会有问题。而且如果要获得程序返回值,可以在调用 Popen.communicate()
之后取 Popen.returncode
的值。
结论:如果使用 subprocess.Popen
,就不使用 Popen.wait()
,而使用 Popen.communicate()
来等待外部程序执行结束。
Popen.wait()¶
-
Wait for child process to terminate. Set and returnreturncode attribute.
Warning
This will deadlock when using stdout=PIPE and/orstderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.
- Popen.communicate(input=None)¶
-
Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate. The optionalinput argument should be a string to be sent to the child process, orNone, if no data should be sent to the child.
communicate() returns a tuple (stdoutdata, stderrdata).
Note that if you want to send data to the process’s stdin, you need to create the Popen object with stdin=PIPE. Similarly, to get anything other thanNone in the result tuple, you need to give stdout=PIPE and/orstderr=PIPE too.
Note
The data read is buffered in memory, so do not use this method if the data size is large or unlimited.
subprocess 的两种方法:
1)如果想调用之后直接阻塞到子程序调用结束:
Depending on how you want to work your script you have two options. If you want the commands to block and not do anything while it is executing, you can just use
subprocess.call
.#start and block until done
subprocess.call([data["om_points"],">", diz['d']+"/points.xml"])2)非阻塞的时候方式:
If you want to do things while it is executing or feed things into
stdin
, you can usecommunicate
after thepopen
call.#start and process things, then wait
p = subprocess.Popen(([data["om_points"],">", diz['d']+"/points.xml"])print"Happens while running"
p.communicate()#now waitAs stated in the documentation,
wait
can deadlock, so communicate is advisable.
Python subprocess.Popen中communicate()和wait()区别的更多相关文章
- python subprocess popen 静默模式(不弹出console控制台)
python subprocess popen 静默模式(不弹出console控制台) import subprocess,sys IS_WIN32 = 'win32' in str(sys.plat ...
- Python subprocess.Popen communicate() 和wait()使用上的区别
之所以会纠结到这个问题上是因为发现在调用Popen的wait方法之后程序一直没有返回.google发现wait是有可能产生死锁的.为了把这个问题彻底弄清楚,搜索一些资料过来看看: 原文链接:http: ...
- Python: subprocess.Popen()不支持unicode问题解决
起源: 所下载视频,有音视频分离者,需要合并起来,采用python之subprocess.Popen()调用ffmpeg实现.python版本为2.7.13,而音视频文件路径,有unicode字符者, ...
- Python Subprocess Popen 管道阻塞问题分析解决
http://ju.outofmemory.cn/entry/279026 场景:1>不断播放mp3文件: 2>使用订阅发布模式保持tcp长连接,从服务器接收信息 造成程序hang死,但是 ...
- Python subprocess Popen
目的:顺序执行进程 在Bash里面类似 a.sh && b.sh && c.sh 先来说下Popen这个函数 class subprocess.Popen(args ...
- python subprocess.Popen 非阻塞
1.非阻塞设置subprocess.Popen(args, stdout=subprocess.PIPE,stderr=subprocess.PIPE) def non_block_read(outp ...
- python subprocess.Popen 控制台输出 实时监控百度网ping值
import subprocess file_out = subprocess.Popen('ping www.baidu.com', shell=True, stdout=subprocess.PI ...
- 【python】json中load和loads区别
相同点 dump 和 dumps 都实现了序列化 load 和 loads 都实现反序列化 变量从内存中变成可存储或传输的过程称之为序列化序列化是将对象状态转化为可保存或可传输格式的过程. 变量内容从 ...
- Python面试题之Python和Java中Super方法的区别
python 的 super 是一个函数,需要两个参数,第一个参数是类,第二个参数是实例,返回值是一个类对象. 其意义是:站在参数2这个实例的角度看去, 参数1这个类的‘父亲’是谁,把‘父亲’返回. ...
随机推荐
- ionic 2 起航 控件的使用 客户列表场景(三)
我们来看看客户列表的搜索控件是怎么工作的吧. 1.打开customer.html <ion-content> <ion-searchbar [(ngModel)]="sea ...
- 聊聊javascript的事件
javascript事件1.点击事件 onclick obtn.click=function(){};2.移入/移出事件 onmouseover/onmouseout 注意:在父级中移入移出,进 ...
- C基础的练习集及测试答案(40-50)
40.(课堂)打印杨辉三角型前10行 #if 0 40.(课堂)打印杨辉三角型前10行 思路分析: 一.打印十行杨辉三角得第十行长度为十,所以建立一个长度为十的数组,作为每行的数据存储 二.按 0-9 ...
- Android(java)学习笔记92:Android线程形态之 AsyncTask (异步任务)
1. AsyncTask和Handler的优缺点比较: 1)AsyncTask实现的原理和适用的优缺点 AsyncTask是Android提供的轻量级的异步类,可以直接继承AsyncTa ...
- Andrew NG 自动化所演讲(20140707):DeepLearning Overview and Trends
出处 以下内容转载于 网友 Fiona Duan,感谢作者分享 (原作的图片显示有问题,所以我从别处找了一些附上,小伙伴们可以看看).最近越来越觉得人工智能,深度学习是一个很好的发展方向,应该也是未来 ...
- Math类小结
package com.swift; public class MathDemo { public static void main(String[] args) { // TODO Auto-gen ...
- Smallest Common Multiple-freecodecamp算法题目
Smallest Common Multiple 1.要求 找出能被两个给定参数和它们之间的连续数字整除的最小公倍数. 2.思路 设定一个twoMultiple(a,b)函数,求出输入两个参数的最小公 ...
- 32-1题:不分行从上到下打印二叉树/BFS/deque/queue
题目 从上往下打印出二叉树的每个节点,同层节点从左至右打印. 考点 1.广度优先遍历 2.binary tree 3.queue 4.deque 思路 按层打印:8.6.10.5.7.9.11 用ST ...
- 线段树和zkw线段树
作者作为一个蒟蒻,也是最近才自学了线段树,不对的地方欢迎大佬们评论,但是不要喷谢谢 好啦,我们就开始说说线段树吧 线段树是个支持区间操作和查询的东东,平时的话还是蛮实用的 下面以最基本的区间加以及查询 ...
- shell脚本:变量,文件判断,逻辑运算等纪要
shell脚本中的变量定义,引用各有不同的方式,除此之外,很常用的有文件属性判断,逻辑运算,数值运算等,下面记录一下它们的属性作用 变量 shell变量的定义分为两种:一种是直接赋值定义,另一种是嵌套 ...