天天看点

比较multiprocessing和subprocess模块

1、subprocess: 和外部进行交互,如调用外部的一个.py文件(适用于两个.py文件无法同时跑的情况)

2、multiprocessing:和threading有点类似,调用该文件内部的某个函数作为子进程运行,可以提高效率,比如开启多个子进程同时跑。

关于python的进程,常用的库有两个:multiprocessing和subprocess模块。

具体使用时,想要实现并发调用外部指令,应该用哪个模块呢?

研究下两个模块区别:

multiprocessing的核心机制是fork,重开一个进程,首先会把父进程的代码copy重载一遍,但是在windows平台上是不支持fork的,那windows上如何使用呢?

--答案是,if main入口中,就可以照常使用multiprocessing(忘记为啥了/试出来的);

subprocess适用于与外部进程交互,调用外部进程;

那么,如下场景:pc连接手机,想要持续捕捉手机adb日志,然后启动一个app进程,如何实现?

首先,如果使用multiprocessing:

//#coding=utf-8

from multiprocessing import Process

import os

myCmd1='adb logcat -v time>c:/log/ll.txt'

myCmd2='adb shell monkey -p com.yoosal.kanku -s 500 --ignore-crashes --ignore-timeouts --monitor-native-crashes --bugreport --throttle 1000 -v -v -v 100000'

//子进程要执行的代码

def run_proc1(name):

os.system(myCmd1)

def run_proc2():

os.system(myCmd2)

if name== 'main':

p1 = Process(target=run_proc1,args=('test',))

p2 = Process(target=run_proc2)

p1.start()

p2.start()

p1.join()

p2.join()

print('Child process end.')

运行结果:可正常并行进程1、进程2

如果使用subprocess:

import os

import subprocess

myCmd1='adb logcat -v time>c:/log/ll.txt'

myCmd2='adb shell monkey -p com.yoosal.kanku -s 500 --ignore-crashes --ignore-timeouts --monitor-native-crashes --bugreport --throttle 1000 -v -v -v 100000'

child1=subprocess.Popen(myCmd1, shell=True,stdout=None)

child2=subprocess.Popen(myCmd2, shell=True,stdout=None)

运行结果:可正常并行进程1、进程2

由此可见,multiprocessing也能用于执行外部指令,他们的区别呢???求解

自己查到的答案是:

subprocess 用来执行外部命令,是os.fork() 和 os.execve() 的封装,即先fork一个子进程,再运行新的外部程序,子进程不会把父进程的模块加载一遍;

而multiprocessing的原理是fork,fork()调用:调用1次,返回两次--操作系统自动把当前进程(父进程)复制了一份(子进程),然后,分别在父进程和子进程内返回,父进程返回子进程的pid,子进程返回0,即父进程和子进程都在运行。

对于外部调用来说,使用multiprocessing太占资源。

这里又有另外一个问题:multiprocessing中,调用p.join()等待子进程执行结束,subprocess模块--父进程如何监听子进程结束?

两个方法:

subprocess.Popen()父进程开启子进程后,不管其是否结束,直接执行下一步;

subprocess.Call()父进程一直等待到子进程运行结束,再执行下一步;

现在一种场景:父进程中使用subprocess.Popen()开启了3个子进程,要等到3个子进程全部结束后,父进程再执行下一步,如何处理?

没有找到可以在父进程里,直接一个方法可以判断所有子进程是否结束的方法,那么常规方法就是自己做判断咯:

//监听子进程是否结束,结束则返回True

def listen_to_child(ss):

i=0

while True:

if ss[i].poll()!=None: //poll返回码:0 正常结束;1 sleep;

//2 子进程不存在;-15 kill;None run

i=i+1

if i>=len(ss):

return True