進程池

#模塊:Pool
#導入方法:from multiprocessing import Pool
#原理:
       進程池:一個池子,裏邊有固定數量的進程。這些進程一直處於待命狀態,一旦有任務來,立刻就有進程去處理。
       由於在實際業務中,任務量是有多有少的,若是任務量特別的多,不可能要開對應那麼多的進程數
       開啓那麼多進程首先就須要消耗大量的時間讓操做系統來爲你管理它。其次還須要消耗大量時間讓
       cpu幫你調度它。
       進程池還會幫程序員去管理池中的進程。
#模塊方法:
       from multiprocessing import Pool
       p = Pool(os.cpu_count() + 1)        #規定進程池中的進程數量根據(CPU核數+1)
       
       三種方法:
         map(func,iterable)
         func:進程池中的進程執行的任務函數
         iterable: 可迭代對象,是把可迭代對象中的每一個元素依次傳給任務函數當參數

         apply(func,args=()): 同步的效率,也就是說池中的進程一個一個的去執行任務
         func:進程池中的進程執行的任務函數
         args: 可迭代對象型的參數,是傳給任務函數的參數
         同步處理任務時,不須要close和join
         同步處理任務時,進程池中的全部進程是普通進程(主進程須要等待其執行結束)

         apply_async(func,args=(),callback=None): 異步的效率,也就是說池中的進程一次性都去執行任務
         func:進程池中的進程執行的任務函數
         args: 可迭代對象型的參數,是傳給任務函數的參數
         callback: 回調函數,就是說每當進程池中有進程處理完任務了,返回的結果能夠交給回調函數,由回調函數進行進一步的處理,回調函數只有異步纔有,同步是沒有的
         異步處理任務時,進程池中的全部進程是守護進程(主進程代碼執行完畢守護進程就結束)
         異步處理任務時,必需要加上close和join

         回調函數的使用:
             進程的任務函數的返回值,被當成回調函數的形參接收到,以此進行進一步的處理操做
             回調函數是由主進程調用的,而不是子進程,子進程只負責把結果傳遞給回調函數

#使用方法:
#進程池中的同步處理的效率
from multiprocessing import Pool
import os
import time

#同步進程池
def func(num):
    num+=1
    return num

if __name__ == '__main__':
    #建立進程池對象
    p=Pool(os.cpu_count()+1) #進程池中進程的數量爲CPU核數+1
    #計算代碼執行到這一行的時間
    start = time.time()
    #建立10000個進程
    for i in range(10000):
        #進程池中同步進程的建立方式
        res=p.apply(func,args=(i,))# 同步處理這10000個任務,同步是指,哪怕我進程中有5個進程,也依舊是1個進程1個進程的去執行任務
        print(res)
    #計算同步進程消耗的時間
    end = time.time()
    print(end-start)
    
#############################
#進程池中異步處理的效率
#異步進程池
def func(num):
    num+=1
    return num

if __name__ == '__main__':
    #建立進程池對象
    p=Pool(os.cpu_count()+1) #進程池中進程的數量爲CPU核數+1
    #計算代碼執行到這一行的時間
    start = time.time()
    l = []
    #建立10000個進程
    for i in range(10000):
        #進程池中同步進程的建立方式
        res = p.apply_async(func,args=(i,))# 異步處理這100個任務,異步是指,進程中有5個進程,一下就處理5個任務,接下來哪一個進程處理完任務了,就立刻去接收下一個任務
        l.append(res)
    #必須先關閉進程池
    p.close()
    #再讓主進程等待子進程的執行完畢,不然主進程執行完子進程可能還沒執行完就隨着主進程的結束而結束了(守護進程)
    p.join()
    #計算異步進程消耗的時間
    end = time.time()
    [print(i.get()) for i in l]
    print(end-start)
#############
##小結:異步進程的效率在必定的相同狀況下優於同步進程





################################
##異步進程中的回調函數的應用
from multiprocessing import Pool
import requests
import time,os

def func(url):
    res = requests.get(url)
    print('子進程的pid:%s,父進程的pid:%s'%(os.getpid(),os.getppid()))
    # print(res.text)
    if res.status_code == 200:
        return url,res.text

def cal_back(sta):
    url,text = sta
    print('回調函數的pid', os.getpid())
    with open('a.txt','a',encoding='utf-8') as f:
        f.write(url + text)
    # print('回調函數中!',url)

if __name__ == '__main__':
    p = Pool(5)
    l = ['https://www.baidu.com',
         'http://www.jd.com',
         'http://www.taobao.com',
         'http://www.mi.com',
         'http://www.cnblogs.com',
         'https://www.bilibili.com',
         ]
    print('主進程的pid',os.getpid())
    for i in l:
        p.apply_async(func, args=(i,),callback=cal_back)#
        # 異步執行任務func,每有一個進程執行完任務後,在func中return一個結果,結果會自動的被callback指定的函數,當成形式參數來接收到
    p.close()
    p.join()
相關文章
相關標籤/搜索