一、利用multiprocessing能夠在主進程中建立子進程,提高效率,下面是multiprocessing建立進程的簡單例子,和多線程的使用很是類似
''' 代碼是由主進程裏面的主線程從上到下執行的, 咱們在主線程裏面又建立了兩個子進程,子進 程裏面也是子線程在幹活,這個子進程在主進 程裏面 ''' import multiprocessing import time def f0(a1): time.sleep(3) print(a1) if __name__ == '__main__':#windows下必須加這句 t = multiprocessing.Process(target=f0,args=(12,)) t.daemon=True#將daemon設置爲True,則主線程不比等待子進程,主線程結束則全部結束 t.start() t2 = multiprocessing.Process(target=f0, args=(13,)) t2.daemon = True t2.start() print('end')#默認狀況下等待全部子進程結束,主進程才結束
這裏的結果是直接打印出end就結束了,由於添加了t.daemon=True,join方法在進程裏面也能夠用,跟線程的用法很是類似python
二、進程之間默認是不能共用內存的windows
li = [] def f1(i): li.append(i) print('你好',li) if __name__ =='__main__':#進程不能共用內存 for i in range(10): p = Process(target=f1,args=(i,)) p.start() '''每一個進程都建立一個列表,而後添加一個因素進去, 每一個進程之間的數據是不能共享的
結果如圖數組
若是將代碼改爲threading,因爲線程共用內存,因此結果是不同的,線程操做列表li以前,拿到的是前一個線程操做過的li列表,如圖多線程
三、若是要進程之間處理同一個數據,能夠運用數組以及進程裏面的manager方法,下面代碼介紹的是manager方法app
from multiprocessing import Process from multiprocessing import Manager def f1(i,dic): dic[i] = 200+i print(dic.values()) if __name__ =='__main__':#進程間默認不能共用內存 manager = Manager() dic = manager.dict()#這是一個特殊的字典 for i in range(10): p = Process(target=f1,args=(i,dic)) p.start() p.join()
這裏輸出如圖,表示每一個進程都是操做這個字典,最後的輸出是有10個元素異步
若是是普通的字典,輸出如圖async
四、multiprocessing模塊裏面的進程池Pool的使用函數
(1)apply模塊的使用,每一個任務是排隊執行的線程
from multiprocessing import Process,Pool from multiprocessing import Manager import time def f1(a): time.sleep(2) print(a) if __name__ =='__main__': pool =Pool(5) for i in range(5):#每次使用的時候會去進程池裏面申請一個進程 pool.apply(func=f1,args=(i,)) print('你好')#apply裏面是每一個進程執行完畢了才執行下一個進程 pool.close()#執行完close後不會有新的進程加入到pool,join函數等待全部子進程結束 pool.join()#等待進程運行完畢,先調用close函數,不然會出錯
運行結果如圖blog
(2)apply_async模塊,會比apply模塊多個回調函數,同時是異步的
from multiprocessing import Process,Pool from multiprocessing import Manager import time def Foo(i): time.sleep(1) return i+50 def Bar(arg): print(arg) if __name__ =='__main__': pool = Pool(5) for i in range(10): '''apply是去簡單的去執行,而apply_async是執行完畢以後能夠執行一 個回調函數,起提示做用''' pool.apply_async(func=Foo,args=(i,),callback=Bar)#是異步的 print('你好') pool.close()#不執行close會報錯,由於join的源碼裏面有個斷言會檢驗是否執行了該方法 pool.join()#等待全部子進程運行完畢,不然的話因爲apply_async裏面daemon是設置爲True的,主進程不會等子進程,所欲函數可能會來不及執行完畢就結束了 '''apply_async裏面,等函數Foo執行完畢,它的返回結果會被當作參數 傳給Bar'''
結果如圖
這兩個方法的主要區別如圖