天天看點

比較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