Python多進程之multiprocessing模塊和進程池的實現


1、利用multiprocessing可以在主進程中創建子進程,提升效率,下面是multiprocessing創建進程的簡單例子,和多線程的使用非常相似
'''
代碼是由主進程里面的主線程從上到下執行的,
我們在主線程里面又創建了兩個子進程,子進
程里面也是子線程在干活,這個子進程在主進
程里面
'''
import multiprocessing
import time

def f0(a1):
    time.sleep(3)
    print(a1)
if __name__ == '__main__':#windows下必須加這句

    t = multiprocessing.Process(target=f0,args=(12,))
    t.daemon=True#將daemon設置為True,則主線程不比等待子進程,主線程結束則所有結束
    t.start()

    t2 = multiprocessing.Process(target=f0, args=(13,))
    t2.daemon = True
    t2.start()

    print('end')#默認情況下等待所有子進程結束,主進程才結束

  這里的結果是直接打印出end就結束了,因為添加了t.daemon=True,join方法在進程里面也可以用,跟線程的用法非常相似

2、進程之間默認是不能共用內存的

li = []

def f1(i):
    li.append(i)
    print('你好',li)

if __name__ =='__main__':#進程不能共用內存
    for i in range(10):
        p = Process(target=f1,args=(i,))
        p.start()

'''每個進程都創建一個列表,然后添加一個因素進去,
   每個進程之間的數據是不能共享的

  結果如圖

如果將代碼改成threading,由於線程共用內存,所以結果是不一樣的,線程操作列表li之前,拿到的是前一個線程操作過的li列表,如圖

3、如果要進程之間處理同一個數據,可以運用數組以及進程里面的manager方法,下面代碼介紹的是manager方法

 

from multiprocessing import Process
from multiprocessing import Manager



def f1(i,dic):
    dic[i] = 200+i
    print(dic.values())

if __name__ =='__main__':#進程間默認不能共用內存
    manager = Manager()
    dic = manager.dict()#這是一個特殊的字典


    for i in range(10):
        p = Process(target=f1,args=(i,dic))
        p.start()
        p.join()

  這里輸出如圖,表示每個進程都是操作這個字典,最后的輸出是有10個元素

如果是普通的字典,輸出如圖

 

4、multiprocessing模塊里面的進程池Pool的使用

(1)apply模塊的使用,每個任務是排隊執行的

from multiprocessing import Process,Pool
from multiprocessing import Manager
import time


def f1(a):
    time.sleep(2)
    print(a)

if __name__ =='__main__':
    pool =Pool(5)
    for i in range(5):#每次使用的時候會去進程池里面申請一個進程
        pool.apply(func=f1,args=(i,))
        print('你好')#apply里面是每個進程執行完畢了才執行下一個進程
    pool.close()#執行完close后不會有新的進程加入到pool,join函數等待所有子進程結束
    pool.join()#等待進程運行完畢,先調用close函數,否則會出錯

  運行結果如圖

(2)apply_async模塊,會比apply模塊多個回調函數,同時是異步的

from multiprocessing import Process,Pool
from multiprocessing import Manager
import time



def Foo(i):
    time.sleep(1)
    return i+50

def Bar(arg):
    print(arg)

if __name__ =='__main__':
    pool = Pool(5)
    for i in range(10):

        '''apply是去簡單的去執行,而apply_async是執行完畢之后可以執行一
        個回調函數,起提示作用'''
        pool.apply_async(func=Foo,args=(i,),callback=Bar)#是異步的
        print('你好')
    pool.close()#不執行close會報錯,因為join的源碼里面有個斷言會檢驗是否執行了該方法
    pool.join()#等待所有子進程運行完畢,否則的話由於apply_async里面daemon是設置為True的,主進程不會等子進程,所欲函數可能會來不及執行完畢就結束了
'''apply_async里面,等函數Foo執行完畢,它的返回結果會被當做參數
    傳給Bar'''

  結果如圖

這兩個方法的主要區別如圖

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM