進程池的概念
開進程池是爲了效率,進程直接的切換是屬於IO調度,每個進程的內存空間都有自己的寄存器,堆棧和文件。那進程池是幹啥? 能指定存放多少個進程,在Python中是先將這些進程創建好,當你創建了50個進程,有某一時間有任務來了,這50個進程並不是一起都去參與工作的,而是排隊例如下圖,進程池嗷嗷待哺的小雞,等待着期待着任務的調度。
在這裏我們要區分信號量,信號量是多個進程進行排隊
這兩張圖我們就可以區分出,單個進程和進程池的概念。
multiprocessing模塊
multiprocessing模塊提供了一個process類來代表一個進程對象,這個模塊表示像線程一樣管理進程,這個是multiprocessing的核心,它與threading相似,對多核的CPU的利用率會比threading更好。
對於multiprocessing中的process類的構造方法如下:
_init_(self, group=None, target=None, name=None, args=(), kwargs={})
參數說明:
group:進程所屬組。(一般爲缺省)
target:表示調用對象。
args:表示調用對象的位置參數元組。
name:別名
kwarges:表示調用對象的字典。
import multiprocessing
def do(n) :
#獲取當前進程的名字
name = multiprocessing.current_process().name
print(name,'starting')
print("worker ", n)
return
if __name__ == '__main__' :
numList = []
for i in range(5):
p = multiprocessing.Process(target=do, args=(i,))
numList.append(p)
p.start()
p.join()
print("Process end.")
運行結果:
Process-1 starting
worker 0
Process end.
Process-2 starting
worker 1
Process end.
Process-3 starting
worker 2
Process end.
Process-4 starting
worker 3
Process end.
Process-5 starting
worker 4
Process end.
Pool方法
pool是什麼?pool就是我們的進程池了,讓我們來看一下怎麼用這個方法
進程池 : from multiprocessing import Pool
創建進程池 : Pool( numprocess , initializer , initargs )
參數 :
numprocess : 要創建的進程數,如果省略,默認使用cpu_count() + 1的值
initializer : 每個工作進程啓動時要執行的可調用對象,默認爲None
initargs : 是要傳給initializer的參數組
import multiprocessing# 導入進程包
import os
import time # os,time這兩個包的作用皆爲更好的體現出我們的進程
def copy(index):
print("當前進程編號",os.getpid())
print(index)
time.sleep(1) # 打一個時間差,更容易看出其效果
if __name__ == '__main__':
pool = multiprocessing.Pool(3) # 導入進程池,括號內爲最大進程數
for i in range(10):
pool.apply_async(copy,(i,))
pool.close()
pool.join()
Pool的括號內爲進程池的容量,就是子進程的最大開啓數量。
我們來看一下運行結果吧
是不是一目瞭然,池容量爲3,所以進程就是三個爲一組的運行
進程池的其他機制
map()
map(func, iterable[, chunksize=None])
pool類中的map方法,與內置的map函數用法基本一致,會使進程阻塞直到結束返回。
close()
關閉進程池,使其不再接受新的任務。
terminal()
結束工作進程,不再處理未處理的任務。
join()
主進程阻塞等待子進程的推出,join方法要在close或terminate之後使用。
練習:下載器
import time
from multiprocessing import Pool
def down_load(movie_name):
"""下載器"""
for i in range(5):
print("電影:{},下載進度{}%".format(movie_name,(i/4*100)))
time.sleep(1)
return movie_name
def alert(movie_name):
print("電影:{}下載完成了。。。。".format(movie_name))
if __name__=="__main__":
movie_list=["西紅柿首富","功夫熊貓","囧媽","泰囧","紅海行動","攀登者"]
pool = Pool(3) # 創建進程池
for movie_name in movie_list:
# 調用進程池
pool.apply_async(down_load,(movie_name,),callback=alert)
pool.close()
pool.join()
運行結果: