天天看點

python開啟多程序(使用程序池multiprocessing.Pool)一、摘要二、示例三、注意事項及建議

一、摘要

python和java、C++不一樣,java一般在進行多項耗時計算時常采用多線程,而python則更适合采用多程序。關于線程和程序的差別,這裡不作詳細解釋。這裡介紹一種python開啟多程序的方法,使用multiprocessing.Pool程序池。

二、示例

import traceback
from multiprocessing import Pool
import time

def work(province, arr):
    #在這裡進行複雜或耗時的計算
    time.sleep(10)
    print(arr)
    print(time.strftime("%Y-%m-%d %H:%M:%S"), "finish....", province)
    arr.append("新資料:" + province)
    return arr

def workMulti(province, arr):
    try:
        work(province, arr)
    except Exception as e:
        print('Error: %s' % (province), traceback.print_exc())

if __name__ == '__main__':
    provinces = ["北京市", "天津市", "上海市", "重慶市", "河北省",
                "河南省", "雲南省", "遼甯省", "黑龍江省", "湖南省",
                "廣西壯族自治區", "廣東省", "海南省"]
    arr=["原資料"]
    po = Pool(processes=5) #允許開幾個程序
    for province in provinces:
        print("Add task:", province)
        # 開啟程序運作workMulti函數,傳入參數province,arr。
        # 注意最後一個逗号是必須的,不是多餘的
        po.apply_async(workMulti, args=(province,arr,))
    print("AAA****************************")
    po.close() #關閉程序池入口,此後不能再向程序池中添加任務了
    print("BBB****************************")
    po.join() #阻塞等待,隻有程序池中所有任務都完成了才往下執行
    print("CCC****************************")
           

這裡開啟多程序去簡單列印省份,實際應用中隻需把複雜或耗時的計算放到work中即可。運作結果如下:

python開啟多程式(使用程式池multiprocessing.Pool)一、摘要二、示例三、注意事項及建議

三、注意事項及建議

1、關于程序的開啟代碼一定要放在if __name__ == '__main__':代碼之下,不能放到函數中或其他地方。

2、po.apply_async(workMulti, args=(province,arr,))開啟程序調用workMulti,需要幾個參數傳幾個,最後需要加一個逗号,因為其傳遞的參數是tuple類型。

3、程序之間的參數變量是不共享的, 在某個程序中修改其函數參數, 在其他程序中是不可見的。這裡每次列印的都是['原資料']足以說明。

4、程序池接受任務并非阻塞式。這裡程序池雖然隻開5個,但它可以一次性接受很多任務, 任務的執行由程序池Pool自行安排,這裡列印的Add task是連續的,并不需要等待程序池有空程序。

5、這裡為何要調用workMulti而不直接調用work?

答:假如work函數中報錯,你會發現程式看起來運作正常,你将發現不了錯誤。通過在workMulti中加入try:...except:...以及traceback.print_exc(),我們可以列印出程序運作的異常。

6、多程序如何接收計算結果?

答:方法1:使用callback回調方法,我沒使用過,不詳細說明

       方法2:在程序中把計算結果儲存下來,如儲存到資料庫或檔案,所有程序計算結束後再提取。我多采用這種方法,這種方法在部分程序計算失敗後仍然能保留計算成功的那些結果。

7、開啟多少個程序合适?

答:看你跑的是什麼類型的任務。如果是計算密集型(耗CPU的),建議開啟和CPU核心線程數一樣的程序,如果同時你還要操作計算機或進行其他任務,那最好再留出一點CPU,不然将會卡死。如果是耗時型(不耗CPU,如網絡請求等),可以考慮開多一些程序,不需要考慮CPU核心線程數。

author:藍何忠

email:[email protected]