Python進程池

進程池的概念

開進程池是爲了效率,進程直接的切換是屬於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()

運行結果:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章