為什么會有進程池的概念?
當我們開啟50個進程讓他們都將100這個數減1次減到50,你會發現特別慢!
效率問題,原因:
1,開辟內存空間。因為每開啟一個進程,都會開啟一個屬於這個進程池的內存空間,因為進程與進程之間數據是完全隔離的。
2,並且這些獨立的內存空間會有許多寄存器,堆棧,文件等,他們存着這個進程里面的變量和數據等。所以生成這些東西都會耗時。
3,生成這么多進程,都需要系統調度,這個也會耗時。不僅這樣,還會涉及到進程使用cpu的時候,當a進程使用一段時間cpu,b進程要去使用cpu,za和b中間的節點不僅要記錄a進程執行到這,還要調用b進程之前執行的結果,所以在這個節點不僅涉及到cpu的切換,還涉及到寄存器,堆棧等包含的數據,還有內存空間的切換。
所以,我們不會無休止的去開啟進程,而是設計一個池子,這個池子就是進程池。
進程池的含義?
python中的進程池,在你還沒有創建進程之前,先創建一個屬於進程的池子。這個池子指定能存放多少個進程,比如說5個進程,因此會先創建這5個進程。當任務進來的時候,比如說50個任務需要50個進程去處理,但是不會生成50個進程,而是排隊去進程池里面拿進程處理任務,所以同一時刻最多有5個進程在處理任務,當任務處理完畢,不會將進程銷毀,而是放回到進程池,在讓其他任務進來讓這些進程處理。
所以,進程池的優點有:
1,提高效率,節省開辟進程和開辟內存空間的時間及銷毀進程的時間。
2,節省內存空間。
更高級的進程池:
這種進程池不給設置固定數量的進程,而是有一個范圍,比如最少3個進程,最多30個進程。當任務或用戶量增加時,進程池里面的進程數量會加加加,一直加到最大值,當任務或用戶量減少,造成很多進程長時間沒用,就會減減減,直到減到最小值。這樣做的好處會系統回收用不到的進程,會給操作系統減負。
但是python里面只有第一種進程池,他不會將進程池進行收縮。
怎么使用?如下代碼:
from multiprocessing import Pool def func(n): for i in range(3): print(n +1) # 將傳入的值打印三次,1到10每個值打印三次 if __name__ == "__main__": pool = Pool(5) # 創建了一個包含5個進程的進程池 pool.map(func, range(10)) # 這樣用map就起進程了,另外range(10)這個位置傳的值一定要是可迭代的,map只能傳可迭代的。10個任務
# map是異步的,並且不需要close()和join(),並且把每一個返回值放到一個列表中,直接顯示出來。
進程池的效率測試:
from multiprocessing import Pool import time def func(n): for i in range(10): # 將1到100,每個數打印十次 print(n +1) if __name__ == "__main__": start = time.time() pool = Pool(5) pool.map(func, range(100)) # 一百個任務 t2 = (time.time() - start) print(t2) # 打印花費時間,時間是0.26130008697509766
然后看起100個進程去處理相同數量的任務:
from multiprocessing import Process import time def func(n): for i in range(10): # 同樣將1到100,每個數打印十次 print(n+1) if __name__ == "__main__": t1 = time.time() p_list = [] for i in range(100): p = Process(target=func, args=(i,)) p_list.append(p) p.start() for p in p_list: p.join() t2 = (time.time() - t1) print(t2) # 3.882610321044922
對比時間差別太大了,進程池的5個進程卻比創建100個進程做同樣的事兒快的太多了。
合並到同一個代碼里面再看效果:
from multiprocessing import Process, Pool import time
def func(n): for i in range(10): print(n + 1) if __name__ == "__main__": t1 = time.time() pool = Pool(5) pool.map(func, range(100)) t2 = time.time() - t1 t3 = time.time() p_list = [] for i in range(100): p = Process(target=func, args=(i,)) p_list.append(p) p.start() for p in p_list: p.join() t4 = time.time() - t3 print(t2, t4)
打印結果:
0.2582840919494629 4.1498963832855225
所以,進程池的效率比開多個進程效率高得多。