首页 > 应用开发 > IT综合 > 【Python】 多进程与多线程
Python中可以执行shell命令的相关模块和函数有:
随着Python版本的更新,过多的模块引起代码的复杂与冗余,因此Python新引入了一个模块subprocess,将以上几个模块中的功能集中到它当中,以后我们只需import这一个即可。
subprocess的目的就是启动一个新的进程并且与之通信。
1. call与check_call
父进程等待子进程执行命令,返回子进程执行命令的状态码,如果出现错误,不进行报错
【这里说的返回执行命令的状态码的意思是:如果我们通过一个变量 res = subprocess.call(['dir',shell=True]) 获取的执行结果,我们能获取到的是子进程执行命令执行结果的状态码,即res=0/1 执行成功或者不成功,并不代表说看不到执行结果,在Python的console界面中我们是能够看到命令结果的,只是获取不到。想获取执行的返回结果,请看check_output。】
【不进行报错解释:如果我们执行的命令在执行时,操作系统不识别,系统会返回一个错误,如:abc命令不存在,这个结果会在console界面中显示出来,但是我们的Python解释器不会提示任何信息,如果想让Python解释器也进行报错,请看check_call】
Popen
实际上,subprocess模块中只定义了一个类: Popen。上面的几个函数都是基于Popen()的封装(wrapper)。从Python2.4开始使用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)
与上面的封装不同,Popen对象创建后,主程序不会自动等待子进程完成。我们必须调用对象的wait()方法,父进程才会等待 (也就是阻塞block)。
1.不等待子进程看出Python执行print操作是在child子进程操作完成以后才进行的。
此外,你还可以在父进程中对子进程进行其它操作,比如我们上面例子中的child对象:
child.poll() # 检查子进程状态
child.kill() # 终止子进程
child.send_signal() # 向子进程发送信号
child.terminate() # 终止子进程 ps: 子进程的PID存储在child.pid
子进程的标准输入、标准输出和标准错误如下属性分别表示:
child.stdin | child.stdout | child.stderr
我们还可以在Popen()建立子进程的时候改变标准输入、标准输出和标准错误,并可以利用subprocess.PIPE将多个子进程的输入和输出连接在一起,构成管道(pipe),如下2个例子:
例1 #!/usr/bin/env python import subprocess child = subprocess.Popen(['ls','-l'],stdout=subprocess.PIPE) #将标准输出定向输出到subprocess.PIPE
print child.stdout.read() #使用 child.communicate() 也可
输出结果:
[root@localhost script]# python sub.py
total 12-rw-r--r--. 1 root root 36 Jan 23 07:38 analyse.sh -rw-r--r--. 1 root root 446 Jan 25 19:35 sub.py
例2
#!/usr/bin/env python
import subprocess child1 = subprocess.Popen(['cat','/etc/passwd'],stdout=subprocess.PIPE) child2 = subprocess.Popen(['grep','root'],stdin=child1.stdout,stdout=subprocess.PIPE)
print child2.communicate()
输出结果为
('root:x:0:0:root:/root:/bin/bash\n, None)
subprocess.PIPE实际上为文本流提供一个缓存区。child1的stdout将文本输出到缓存区,随后child2的stdin从该PIPE中将文本读取走。child2的输出文本也被存放在PIPE中,直到communicate()方法从PIPE中读取出PIPE中的文本。
注意:communicate()是Popen对象的一个方法,该方法会阻塞父进程,直到子进程完成
子进程命令解释
在上面的例子中我们创建子进程时,全部是调用Python进行解释,但Python并没有将所有命令全部解释,当Python不能进行解释时,就绪要调用系统来进行执行。
#!/usr/bin/env python
import subprocess subprocess.Popen(['ls','-l']) subprocess.Popen(['ifconfig|grep 127.0.0.1'],shell=True)
结果
>>> subprocess.Popen(['ifconfig|grep 127.0.0.1'],shell=True) >>> inet addr:127.0.0.1 Mask:255.0.0.0
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29096438/viewspace-2150311/ ,如需转载,请注明出处,否则将追究法律责任。