python中进程池的应用
#原創,轉載請聯系
假設我們寫的一個程序需要運行100個子進程的時候,那么寫程序時,不可能循環創建銷毀100個進程吧?進程的創建與銷毀是很耗系統的資源的。
進程池的作用就體現出來了。
進程池可以控制進程的數量,重復利用進程對象,減少創建和銷毀進程的開銷。
-----------------------------------------------------------------------------------------我是一條分割線----------------------------------------------------------------------------------------------------
1.創建進程池
pool = multiprocessing.Pool()創建進程池可以接收一個參數,這個參數可以設置進程池的最大值。就是指定有幾個子進程在“同時”進行。(為什么說是“同時”,因為在并發的情況下,子進程和主進程是按照時間片輪尋的方式執行的,只是切換得過快,并不是真的一起運行。)
-----------------------------------------------------------------------------------------我是一條分割線----------------------------------------------------------------------------------------------------
2.進程池的應用
import multiprocessing import os import random import timedef run_time(index):start_time = time.time()time.sleep(random.random())print("任務%d 任務id為%d 任務運行的時間為%0.2f" % (index,os.getpid(),time.time()-start_time))if __name__ == '__main__':pool = multiprocessing.Pool(3)for i in range(10):pool.apply_async(func=run_time,args=(i,))pool.close()pool.join()print("結束標志")輸出:
任務2? 任務id為3191? 任務運行的時間為0.29
任務1? 任務id為3190? 任務運行的時間為0.33
任務0? 任務id為3189? 任務運行的時間為0.45
任務3? 任務id為3191? 任務運行的時間為0.41
任務4? 任務id為3190? 任務運行的時間為0.39
任務5? 任務id為3189? 任務運行的時間為0.76
任務7? 任務id為3190? 任務運行的時間為0.52
任務6? 任務id為3191? 任務運行的時間為0.80
任務8? 任務id為3189? 任務運行的時間為0.56
任務9? 任務id為3190? 任務運行的時間為0.80
結束標志
-----------------------------------------------------------------------------------------我是一條分割線----------------------------------------------------------------------------------------------------
3.進程池的進程默認都是守護進程
進程池的子進程都是由主進程創建的,且默認都是守護進程。所以當主進程執行完之后,進程池的子進程全部都被中斷。如果需要執行完進程池的子進程,才結束程序,需要加上兩句代碼。
pool.close() # 必須先關閉進程池,不再讓它接收新的進程,才能進行下一步的阻塞。(已經在排隊的進程不算新進程了!例如上面的例子,10個子進程已經在進程池排隊,所以join方法會阻塞直到10個子進程執行完成。) pool.join()
上面的例子,如果沒有這兩句代碼,輸出會變成下面的結果
import multiprocessing import os import random import timedef run_time(index):start_time = time.time()time.sleep(random.random())print("任務%d 任務id為%d 任務運行的時間為%0.2f" % (index,os.getpid(),time.time()-start_time))if __name__ == '__main__':pool = multiprocessing.Pool(3)for i in range(10):pool.apply_async(func=run_time,args=(i,))print("結束標志")輸出:
結束標志
進程池排隊的10個進程,都是守護進程。還沒來得及運行,主進程運行了,然后中斷了進程池所有的子進程,因次子進程并沒有輸出。
-----------------------------------------------------------------------------------------我是一條分割線----------------------------------------------------------------------------------------------------
4.進程池中子進程之間的通信。
關于進程間的通信,可以看我的另一篇博客。https://www.cnblogs.com/chichung/p/9533227.html
那么,進程池中的子進程之間怎么進行通信呢?
我們來在進程池創建兩個子進程,然后讓一個子進程把數據放在隊列,另外一個子進程在隊列里取數據。
import multiprocessing import timedef send_data(queue):for i in "python":queue.put(i)print("把%s放進隊列里" % i)def recv_data(queue):while not queue.empty():data = queue.get()print("在隊列里取得%s" % data)if __name__ == '__main__':q = multiprocessing.Manager().Queue(5) # 進程池之間的通信中間要加Manager(),單純進程間的通信并不用,這是最大的區別。 pool = multiprocessing.Pool(2)pool.apply_async(func=send_data,args=(q,))time.sleep(1)pool.apply_async(func=recv_data,args=(q,))time.sleep(1)pool.close()pool.join()print("結束標志")輸出:
把p放進隊列里
把y放進隊列里
把t放進隊列里
把h放進隊列里
把o放進隊列里
在隊列里取得p
把n放進隊列里
在隊列里取得y
在隊列里取得t
在隊列里取得h
在隊列里取得o
在隊列里取得n
結束標志
進程池里面子進程的通信也是用到Queue隊列,但是創建的方式稍微有點不同,上面代碼注釋那里已經提出。
?
轉載于:https://www.cnblogs.com/chichung/p/9534491.html
總結
以上是生活随笔為你收集整理的python中进程池的应用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 第十三节、SURF特征提取算法
- 下一篇: tp5.0初入