subprocess被用来替换一些老的模块和函数,如:os.system、os.spawn*、os.popen*、popen2.*、commands.*。

subprocess的目的就是启动一个新的进程并且与之通信。

1.Popen

subprocess模块中只定义了一个类: Popen。可以使用Popen来创建进程,并与进程进行复杂的交互。它的构造函数如下:

subprocess.Popen(args, bufsize=0, executable=None, stdin=None, stdout=None, stderr=None, preexec_fn=None, close_fds=False, shell=False, cwd=None, env=None, universal_newlines=False, startupinfo=None, creationflags=0)

其参数解释如下所示:

参数

说明

args

字符串或者列表

bufsize

0 无缓冲
1 行缓冲
其他正值 缓冲区大小
负值 采用默认系统缓冲(一般是全缓冲)

executable

一般不用吧,args字符串或列表第一项表示程序名

stdin
stdout
stderr

None 没有任何重定向,继承父进程
PIPE 创建管道
文件对象
文件描述符(整数)
stderr 还可以设置为 STDOUT

preexec_fn

钩子函数, 在fork和exec之间执行。(unix)

close_fds

unix 下执行新进程前是否关闭0/1/2之外的文件
windows下不继承还是继承父进程的文件描述符

shell

为真的话
unix下相当于args前面添加了 "/bin/sh“ ”-c”
window下,相当于添加"cmd.exe /c"

cwd

设置工作目录

env

设置环境变量

universal_newlines

各种换行符统一处理成 '\n'

startupinfo

window下传递给CreateProcess的结构体

creationflags

windows下,传递CREATE_NEW_CONSOLE创建自己的控制台窗口

(1)子进程的简单控制

例 1#!/usr/bin/python3
import subprocess
pingP = subprocess.Popen(args='ping -n 4 www.baidu.com',shell=True) print(pingP.pid) print(pingP.returncode)

执行结果如下所示:

D:\workspace\Python\python3\practise\subprocess>python3 demo01.py
2356
NoneD:\workspace\Python\python3\practise\subprocess>
Pinging www.a.shifen.com [115.239.210.27] with 32 bytes of data:
Reply from 115.239.210.27: bytes=32 time=9ms TTL=57
Reply from 115.239.210.27: bytes=32 time=11ms TTL=57
Reply from 115.239.210.27: bytes=32 time=26ms TTL=57
Reply from 115.239.210.27: bytes=32 time=7ms TTL=57Ping statistics for 115.239.210.27:Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:Minimum = 7ms, Maximum = 26ms, Average = 13ms

从输出可以看出,代码生产了一个子进程并执行了args中指定的命令,然后执行下面的语句。由于网络应用的延迟,这就使得在打印出了进程ID和返回值后才输出外部命令的输出。

由于外部程序是在一个新生成的子程序中执行的,所以如果不加以限制,则有可能回将原进程和子进程的输出混淆。如果需要等待该子进程结束,可以使用Popen类中的wait()函数,如下面的代码所示:

例2#!/usr/bin/python3
import subprocess
pingP = subprocess.Popen(args='ping -n 4 www.baidu.com',shell=True)
pingP.wait()   #等待进程完成
print(pingP.pid)
print(pingP.returncode)

执行结果如下所示:

D:\workspace\Python\python3\practise\subprocess>python3 demo01.pyPinging www.a.shifen.com [115.239.210.27] with 32 bytes of data:
Reply from 115.239.210.27: bytes=32 time=14ms TTL=57
Reply from 115.239.210.27: bytes=32 time=7ms TTL=57
Reply from 115.239.210.27: bytes=32 time=6ms TTL=57
Reply from 115.239.210.27: bytes=32 time=17ms TTL=57Ping statistics for 115.239.210.27:Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:Minimum = 6ms, Maximum = 17ms, Average = 11ms
18508
0

wait()函数将等待子进程的完成,将会返回子进程的返回值。

从上面的输出中可以看到,现在子进程的进程ID和返回值已经在子进程输出的后面了。同时,子进程的返回值已经变为0,表示子进程已经顺利退出。

此外,你还可以在父进程中对子进程进行其它操作,比如我们上面例子中的child对象:

pingP.poll() # 检查子进程状态
pingP.kill() # 终止子进程
pingP.send_signal() # 向子进程发送信号
pingP.terminate() # 终止子进程
ps: 子进程的PID存储在child.pid

(2) 子进程文本流控制

在上面的两个示例程序中,子进程被创建后,其标准输入、标准输出和标准错误处理都和原进程没有关系。如果要管理子进程的输入输出,可以改变Popen类中的stdin、stdout和stderr等类参数。如何使用以前的进程创建方法,则需要将输入输出重定向。

例 3#!/usr/bin/python3
import subprocesspingP = subprocess.Popen(args='ping -n 4 www.baidu.com',shell=True,stdout = subprocess.PIPE)
pingP.wait()
print(pingP.stdout.read())   #读取进程的输出信息,
print(pingP.pid)
print(pingP.returncode)

代码说明:

  • 在Popen的类参数中,stdin、stdout、stderr分别用来指定程序标准输入、标准输出和标准错误的处理器,其值可以为PIPE、文件描述符和None等。默认值都为None。
  • 在获取输出后,pingP.stdout(<open file '<fdopen>',mode 'rb'>)成为一个可读的文件对象,可以使用相应的文件操作函数来读取。

单单从输出来看,例2和例3的输出是一样的。但是,两者是完全不同的。在例2中,子进程的输出并没有得到控制。而在例3中,其子进程的输出则被收集起来了。如果将脚本中的“print(pingP.stdout.read())”这句注释掉,则程序输出如下:

D:\workspace\Python\python3\practise\subprocess>python3 demo01.py
15404
0

另外一种方式是采用Popen类提供的communicate方法。示例如下

#!/usr/bin/env python
import subprocessch1 = subprocess.Popen(['cat','/etc/passwd'],stdout=subprocess.PIPE)
ch2 = subprocess.Popen(['grep','root'],stdin=ch1.stdout,stdout=subprocess.PIPE)res = ch2.communicate()
print(res)

输出结果为:

('root:x:0:0:root:/root:/bin/bash\n', None)

subprocess.PIPE实际上为文本流提供一个缓存区。ch1的stdout将文本输出到缓存区,随后ch2的stdin从该PIPE中将文本读取走。ch2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。

communicate()方法返回的是一个(stdout,sterr)元组。需要注意的是,communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成。同时,因为数据都是缓存在内存中的,所以如果数据很大的时候不要使用这个方法。

转载于:https://www.cnblogs.com/bdhk/p/7440556.html

使用subprocessm模块管理进程相关推荐

  1. taro 引入js_Taro跨端开发之多业务模块管理 React Native篇(终篇)

    React Native 热更新方案 rn的业务越来越庞大,同时协同的团队越来越多. rn的动态化就必须提上日程了. 对于rn热更新,首当其冲的问题就是分包. rn的基础库很大,再加上我们依赖了很多的 ...

  2. 【Linux 内核】进程管理 ( 进程与操作系统 | 进程与程序 | 进程与线程 | 虚拟地址空间 )

    文章目录 一.进程与操作系统 二.进程与程序 三.进程与线程 四.虚拟地址空间 一.进程与操作系统 操作系统与硬件的关系 : 操作系统 使用 硬件 提供的资源 , 如 CPU , 内存 , 磁盘 , ...

  3. python守护进程进程池_Python3标准库:multiprocessing像线程一样管理进程

    Python Python开发 Python语言 Python3标准库:multiprocessing像线程一样管理进程 1. multiprocessing像线程一样管理进程 multiproces ...

  4. python并行计算进程池通信_Python使用进程池管理进程和进程间通信

    与线程池类似的是,如果程序需要启动多个进程,也可以使用进程池来管理进程.程序可以通过 multiprocessing 模块的 Pool() 函数创建进程池,进程池实际上是 multiprocessin ...

  5. 解析Linux内核的基本的模块管理与时间管理操作---超时处理【转】

    转自:http://www.jb51.net/article/79960.htm 这篇文章主要介绍了Linux内核的基本的模块管理与时间管理操作,包括模块加载卸载函数的使用和定时器的用法等知识,需要的 ...

  6. 面试-操作系统-进程管理-进程-进程调度-死锁

    文章目录 ==概念== 备注 简单说下你对并发和并行的理解? 同步.异步.阻塞.非阻塞的概念? 操作系统概念? 一个程序从开始运行到结束的完整过程,你能说出来多少? 用户态和内核态是如何切换的? 什么 ...

  7. 【Linux鸟哥笔记】20-启动流程、模块管理与Loader

    [Linux鸟哥笔记]20-启动流程.模块管理与Loader 目录浏览 章节学习 BIOS加载 内核功能 init进程 内核与内核模块 Boot Loader: Grub initrd 文件 启动过程 ...

  8. RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2-新增模块管理界面导出功能(可按条件导出)...

    RDIFramework.NET ━ .NET快速信息化系统开发框架 V3.2->新增模块管理界面导出功能(可按条件导出) 导出功能在很多应用场景中都需要,RDIFramework.NET V3 ...

  9. php 进程管理,php如何管理进程

    进程管理-防止进程成为僵尸进程 创建好了进程,那么怎么对子进程进行管理呢? 使用信号,对子进程的管理,一般有两种情况:(推荐学习:PHP编程从入门到精通) posix_kill():此函数并不能顾名思 ...

最新文章

  1. Python 虚拟环境 virtualenv
  2. WIN7电脑文件莫名其妙被删除后的恢复
  3. [C++学习笔记]C++常见问题大全(一)
  4. kafka+zookeeper安装配置
  5. IIS 日志文件位置
  6. 如何开始使用Java中的Lambda表达式
  7. win10安装python的xlrd_win10安装python的xlrd
  8. python廖老师_Python3.5-20190518-廖老师-自我笔记-面向对象
  9. 5G、IoT 爆发前夕,我们必须了解的操作系统! | 码书
  10. 甲骨文裁员后续:近万招聘者哄抢甲骨文前员工
  11. 计算机怎么给课程表涂颜色,Excel做自动统计课时数的彩色课程表
  12. 通用算法(ML,DL)分类判定指标:召回率 Recall、精确度Precision、准确率Accuracy等
  13. Oracle P6培训系列:13分配限制条件
  14. python之二进制
  15. 弱水三千,只取一瓢饮 的意思
  16. 网课答案php源代码,知到网课答案WEB程序设计(PHP)2020章节测试答案
  17. 一文看懂IO多路复用
  18. java课程培训中心
  19. 问题 F: 真值表(Ⅰ) 2022
  20. 不用装闭路电视就可以看CCTV1-10频道电视,在线随心换台包你满意

热门文章

  1. Asp.net服务器端控件CheckBoxList的使用心得
  2. 关于 Visual Studio 2010
  3. linux dd命令使用详解
  4. Best open-source pedestrian detection library for commercial use?
  5. caffe读书笔记1 CIFAR-10在caffe上进行训练与学习
  6. Tone Mapping
  7. Vue CLI 3.0脚手架如何在本地配置mock数据
  8. adb通信协议分析以及实现(二):adb服务进程发现设备
  9. mac安装python3
  10. Javascript中typeof instanceof constructor的区别