Python多進程解決方案multiprocessing ProcessPoolExecutor

 

大多數編程語言都會有多線程和多進程的概念,至於線程和進程的概念,你們能夠百度一下。編程

做爲一門膠水語言,Python絕不意外,也能夠利用多線程和多進程處理併發問題,可是多線程因爲GIL的存在,起做用範圍大打折扣,僅限於在IO等場景能夠發揮點做用。多線程

因此,今天要跟你們分享的是Python多進程方案,更好地利用系統多核,從而提高性能。併發

 

基礎方案一:app

利用Process新建一個子進程,在子進程執行任務。咱們dom

寫一個循環,模擬耗時任務的執行。主進程不會等待子進程執行完,就會繼續往下執行。咱們能夠根據實際業務狀況,開啓不少這樣的進程。async

# encoding=utf-8
from datetime import datetime
import time
from multiprocessing import Pool, Process


def job1():
    def run():
        print('[Child][{}]'.format(datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')))

    # 模擬一個耗時任務
    counter = 0
    while counter < 5:
        run()
        time.sleep(2)
        counter += 1
    #
    print('sub process done')


if __name__ == '__main__':
    p = Process(target=job1)
    p.start()
    #
    print('main process done')

執行效果以下編程語言

 

 

 

方案二:進程池性能

進程池能夠理解成一個隊列,該隊列能夠容易指定數量的子進程,當隊列被任務佔滿以後,後續新增的任務就得排隊,直到舊的進程有任務執行完空餘出來,纔會去執行新的任務。spa

# encoding=utf-8
from datetime import datetime
import time
import random
from multiprocessing import Pool, Process


def job2(msg):
    def run():
        print('[Child-{}][{}]'.format(msg, datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')))

    # 模擬一個耗時任務
    time.sleep(random.randint(1, 3))
    run()


if __name__ == '__main__':
    # 進程池大小
    pool_size = 2
    # 進程池
    pool = Pool(pool_size)
    # 添加任務, 假設咱們要添加6個任務,因爲進程池大小爲2,每次能只有2個任務並行執行,其餘任務排隊
    [pool.apply_async(job2, args=(i,)) for i in range(6)]
    pool.close()
    pool.join()
    #
    print('main process done')

執行結果以下:線程

 

 

 

方案三:ProcessPoolExecutor

ProcessPoolExecutor是concurrent.futures裏面的一個多進程解決方案,對多進程進行了一些便利的封裝,用起來跟Java的ThreadPoolExecutor感受很相似。

一樣,方案二的示例,咱們用ProcessPoolExecutor從新實現一次。

# encoding=utf-8
from datetime import datetime
import time
import random
from concurrent.futures import ProcessPoolExecutor, wait


def job3(msg):
    def run():
        print('[Child-{}][{}]'.format(msg, datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')))

    # 模擬一個耗時任務
    time.sleep(random.randint(1, 5))
    run()


if __name__ == '__main__':
    # 進程池大小
    pool_size = 2
    # 進程池
    pool = ProcessPoolExecutor(pool_size)
    # 添加任務, 假設咱們要添加6個任務,因爲進程池大小爲2,每次能只有2個任務並行執行,其餘任務排隊
    tasks = [pool.submit(job3, i) for i in range(6)]
    ### 等待任務執行完, 也能夠設置一個timeout時間
    wait(tasks)
    #
    print('main process done')

 

 

 

結語

以上簡單介紹了多進程,進程池的幾種用法。固然示例的幾種場景都不涉及到多進程併發變量共享的問題,這個後續會推出其餘文章單獨講述。

相關文章
相關標籤/搜索