進程池,
一、前言
進程池內部維護一個進程式列,當使用時,則去進程池中擷取一個進程,如果進程池序列中沒有可供使用的進程,那麼程式就會等待,直到進程池中有可用進程為止。進程池的作用可以在多進程程式中有效控制進程啟動並執行個數,維護系統的穩定。
二、multiprocessing.pool 2.1 apply(func, args=(), kwds={})
預設阻塞,所有進程是串列的,不建議使用
from multiprocessing import Poolimport timeimport osdef foo(i): time.sleep(2) print('in process', os.getpid()) return i + 100if __name__ == '__main__': # windows 運行進程池一定要加這 pool = Pool(5) # 進程池中進程個數為5,多餘的進程先掛起 for i in range(10): pool.apply(func=foo, args=(i,)) print('end') pool.close() pool.join() # 進程池中進程執行完畢後再關閉,如果注釋,那麼程式直接關閉。
註:所有進程會依次運行,主進程等待所有進程結束
2.2 apply_async(func, args=(), kwds={}, callback=None, error_callback=None)
非阻塞,進程池中的進程並行,支援回調
from multiprocessing import Poolimport timeimport osdef foo(i): time.sleep(1) print('in process', os.getpid()) return i + 100if __name__ == '__main__': # windows 運行進程池一定要加這 pool = Pool(5) # 進程池中進程個數為5,多餘的進程先掛起 for i in range(10): pool.apply_async(func=foo, args=(i,)) print('end') pool.close() pool.join() # 進程池中進程執行完畢後再關閉,如果注釋,那麼程式直接關閉。
三、回呼函數
在apply_async中執行回呼函數,每執行完一個子進程,主進程就調用一下回呼函數,回呼函數執行完後再執行下一個子進程
# -*- coding: UTF-8 -*-from multiprocessing import Poolimport timeimport osdef foo(i): time.sleep(1) print('in process', os.getpid()) return i + 100def bar(arg): # 增加的回到函數, 其實回呼函數是主進程執行的 print('-->exec done:', arg, os.getpid())if __name__ == '__main__': # windows 運行進程池一定要加這 pool = Pool(5) # 進程池中進程個數為5,多餘的進程先掛起 print('main process pid,', os.getpid()) for i in range(10): pool.apply_async(func=foo, args=(i,), callback=bar) # pool.apply(func=foo, args=(i,)) print('end') pool.close() pool.join() # 進程池中進程執行完畢後再關閉,如果注釋,那麼程式直接關閉。
註:通過進程pid可以看出,回呼函數其實是由主進程執行的