進程池的概念,定義一個池子,在里面放上固定數量的進程,有需求來了,就拿一個池中的進程來處理任務,等到處理完畢,進程並不關閉,而是將進程再放回進程池中繼續等待任務。如果有很多任務需要執行,池中的進程數量不夠,任務就要等待之前的進程執行任務完畢歸來,拿到空閑進程才能繼續執行。也就是說,池中進程的數量是固定的,那么同一時間最多有固定數量的進程在運行。這樣不會增加操作系統的調度難度,還節省了開閉進程的時間,也一定程度上能夠實現並發效果
進程池無IO堵塞的情況
# -*- coding: utf-8 -*- import os from multiprocessing import Pool def func(n): return n**2 if __name__ == '__main__': pool = Pool() obj_lst = [] for i in range(6): p_obj = pool.apply_async(func, args=(i,)) # 異步執行進程 obj_lst.append(p_obj) pool.close() # 不再向進程池提交新的任務了 pool.join() # 進程池中的進程都執行完了 print([p_obj.get() for p_obj in obj_lst]) # [0, 1, 4, 9, 16, 25]
# coding:utf-8 import time from multiprocessing import Process, Pool def func(n): pass if __name__ == '__main__': num = 10 start_pool_time = time.time() pool = Pool(5) pool.map(func, range(num)) # map是異步執行的,並且自帶close和join print("通過進程池執行的時間:", time.time() - start_pool_time) std_start_time = time.time() for i in range(num): pass print("正常執行的執行時間:", time.time() - std_start_time) pro_start_time = time.time() p_lst = [] for i in range(num): p = Process(target=func, args=(i,)) p.start() p_lst.append(p) [pp.join() for pp in p_lst] print("多進程的執行時間:", time.time() - pro_start_time) # 通過進程池執行的時間: 0.46875 # 正常執行的執行時間: 0.0 # 多進程的執行時間: 0.828125 #一般約定俗成的是進程池中的進程數量為CPU的數量,工作中要看具體情況來考量。
有IO阻塞的情況
# coding:utf-8 import time from multiprocessing import Process, Pool def func(n): time.sleep(1) if __name__ == '__main__': num = 10 start_pool_time = time.time() pool = Pool(5) pool.map(func, range(num)) print("通過進程池執行的時間:", time.time() - start_pool_time) std_start_time = time.time() for i in range(num): time.sleep(1) print("正常執行的執行時間:", time.time() - std_start_time) pro_start_time = time.time() p_lst = [] for i in range(num): p = Process(target=func, args=(i,)) p.start() p_lst.append(p) [pp.join() for pp in p_lst] print("多進程的執行時間:", time.time() - pro_start_time) # 通過進程池執行的時間: 2.578125 # 正常執行的執行時間: 10.0 # 多進程的執行時間: 1.75
從Python3.2開始,標准庫為我們提供了concurrent.futures模塊,它提供了ThreadPoolExecutor和ProcessPoolExecutor兩個類,實現了對threading和multiprocessing的進一步抽象(這里主要關注線程池),不僅可以幫我們自動調度線程,還可以做到:
1、主線程可以獲取某一個線程(或者任務的)的狀態,以及返回值。
2、當一個線程完成的時候,主線程能夠立即知道。
3、讓多線程和多進程的編碼接口一致。