multiprocessing模塊
如果你打算編寫多進程的服務程序,Unix/Linux無疑是正確的選擇。由於Windows沒有fork
調用,難道在Windows上無法用Python編寫多進程的程序?由於Python是跨平臺的,自然也應該提供一個跨平臺的多進程支持。multiprocessing
模塊就是跨平臺版本的多進程模塊。multiprocessing
模塊提供了一個Process
類來代表一個進程對象,這個模塊表示像線程一樣管理進程,這個是multiprocessing的核心,它與threading很相似,對多核CPU的利用率會比threading好的多。
看一下Process類的構造方法:
__init__(self, group=None, target=None, name=None, args=(), kwargs={})
參數說明:
group:進程所屬組。基本不用
target:表示調用對象。
args:表示調用對象的位置參數元組。
name:別名
kwargs:表示調用對象的字典。
創建子進程時,只需要傳入一個執行函數和函數的參數,創建一個Process實例,並用其start()方法啓動,這樣創建進程比fork()還要簡單。 join()方法表示等待子進程結束以後再繼續往下運行,通常用於進程間的同步。
注意:
在Windows上要想使用進程模塊,就必須把有關進程的代碼寫在當前.py文件的if __name__ == ‘__main__’ :語句的下面,才能正常使用Windows下的進程模塊。Unix/Linux下則不需要。
Pool類
Pool類可以提供指定數量的進程供用戶調用,當有新的請求提交到Pool中時,如果池還沒有滿,就會創建一個新的進程來執行請求。如果池滿,請求就會告知先等待,直到池中有進程結束,纔會創建新的進程來執行這些請求。
下面介紹一下multiprocessing 模塊下的Pool類下的幾個方法:
.apply()
函數原型:apply(func[, args=()[, kwds={}]])
該函數用於傳遞不定參數,同python中的apply函數一致,主進程會被阻塞直到函數執行結束(不建議使用,並且3.x以後不在出現)。
.apply_async
函數原型:apply_async(func[, args=()[, kwds={}[, callback=None]]])
與apply用法一致,但它是非阻塞的且支持結果返回後進行回調。
.map()
函數原型:map(func, iterable[, chunksize=None])
Pool類中的map方法,與內置的map函數用法行爲基本一致,它會使進程阻塞直到結果返回。
注意:雖然第二個參數是一個迭代器,但在實際使用中,必須在整個隊列都就緒後,程序纔會運行子進程。
.map_async()
函數原型:map_async(func, iterable[, chunksize[, callback]])
與map用法一致,但是它是非阻塞的。其有關事項見apply_async。
.close()
關閉進程池(pool),使其不在接受新的任務。
.terminal()
結束工作進程,不在處理未處理的任務。
.join()
主進程阻塞等待子進程的退出, join方法要在close或terminate之後使用。
apply_async(func[, args[, kwds]]) :使用非阻塞方式調用func(並行執行,堵塞方式必須等待上一個進程退出才能執行下一個進程),args爲傳遞給func的參數列表,kwds爲傳遞給func的關鍵字參數列表;異步,多個線程同時執行
apply(func[, args[, kwds]]):使用阻塞方式調用func,執行完一個進程後再去執行其他線程。
close():關閉Pool,使其不再接受新的任務;
terminate():不管任務是否完成,立即終止;
join():主進程阻塞,等待子進程的退出, 必須在close或terminate之後使用;
apply_async(func, args=(), kwds={}, callback=None, error_callback=None):callback:回調函數,可接收func函數的返回值
.注意點: 主進程不會等待子進程結束後,再結束。需要加join()
join()必須放在close語句之後
#!/usr/bin/python
# --*-- coding:utf-8 --*--
import multiprocessing
import sys,os,time
result = []#把運行的進程池放入,空的列表
def run(msg):#定義正在處理進程編號數的函數功能
#打印正在處理的進程編號數與對應的系統進程號
print ('threading number:%s %s' %(msg,os.getpid()))
time.sleep(2)
p = multiprocessing.Pool(processes = 25)#綁定事例,同時執行25個線程
for i in range(100):
result.append(p.apply_async(run,('%s' %i,)))#異步傳輸正在運行的進程數字號碼
p.close()#關閉正在運行的25個進程
#p.join()
for res in result:#獲取運行結果
res.get(timeout=5)