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