Python 進程池


一、定義:

  多進程是實現並發的手段之一,在利用Python進行系統管理的時候,特別是同時操作多個文件目錄,或者遠程控制多台主機,並行操作可以節約大量的時間。                      Pool([numprocess [,initializer [, initargs]]]):創建進程池 

二、主要參數:

  1 numprocess:要創建的進程數,如果省略,將默認使用cpu_count()的值
  2 initializer:是每個工作進程啟動時要執行的可調用對象,默認為None
  3 initargs:是要傳給initializer的參數組

三、主要方法:

p.apply(func [, args [, kwargs]]):在一個池工作進程中執行func(*args,**kwargs),然后返回結果。需要強調的是:此操作並不會在所有池工作進程中並執行func函數。如果要通過不同參數並發地執行func函數,必須從不同線程調用p.apply()函數或者使用p.apply_async()
p.apply_async(func [, args [, kwargs]]):在一個池工作進程中執行func(*args,**kwargs),然后返回結果。此方法的結果是AsyncResult類的實例,callback是可調用對象,接收輸入參數。當func的結果變為可用時,將理解傳遞給callback。callback禁止執行任何阻塞操作,否則將接收其他異步操作中的結果。
   
p.close():關閉進程池,防止進一步操作。如果所有操作持續掛起,它們將在工作進程終止前完成
P.jion():等待所有工作進程退出。此方法只能在close()或teminate()之后調用

四、其它方法:

方法apply_async()和map_async()的返回值是AsyncResul的實例obj。實例具有以下方法
obj.get():返回結果,如果有必要則等待結果到達。timeout是可選的。如果在指定時間內還沒有到達,將引發一場。如果遠程操作中引發了異常,它將在調用此方法時再次被引發。
obj.ready():如果調用完成,返回True
obj.successful():如果調用完成且沒有引發異常,返回True,如果在結果就緒之前調用此方法,引發異常
obj.wait([timeout]):等待結果變為可用。
obj.terminate():立即終止所有工作進程,同時不執行任何清理或結束任何掛起工作。如果p被垃圾回收,將自動調用此函數

五、實例:

from multiprocessing import Pool
import os,time

def work(n):
    print('task <%s> is runing' %os.getpid())
    time.sleep(2)
    return n**2
if __name__ == '__main__':
    # print(os.cpu_count())
    p=Pool(4) # 並行執行幾個進程
    # for i in range(10):
    #     res=p.apply(work,args=(i,))
    #     print(res)

    res_l=[]
    for i in range(10):
        res=p.apply_async(work,args=(i,))
        res_l.append(res)

    p.close()
    p.join()
    #
    # for res in res_l:
    #     print(res.get())

六、回調函數:

import requests #pip3 install requests
import os,time
from multiprocessing import Pool
def get_page(url):
    print('<%s> get :%s' %(os.getpid(),url))
    respone = requests.get(url)
    if respone.status_code == 200:
        return {'url':url,'text':respone.text}

def parse_page(dic):
    print('<%s> parse :%s' %(os.getpid(),dic['url']))
    time.sleep(0.5)
    res='url:%s size:%s\n' %(dic['url'],len(dic['text'])) #模擬解析網頁內容
    with open('db.txt','a') as f:
        f.write(res)


if __name__ == '__main__':
    p=Pool(4)
    urls = [
        'http://www.baidu.com',
        'http://www.baidu.com',
        'http://www.baidu.com',
        'http://www.baidu.com',
        'http://www.baidu.com',
        'http://www.baidu.com',
        'http://www.baidu.com',
    ]


    for url in urls:
        p.apply_async(get_page,args=(url,),callback=parse_page) #callback 則把得到的結果傳給了回調味函數進行處理


    p.close()
    p.join()
    print('主進程pid:',os.getpid())

七、進程池控制套字節的並發通信實例

#客戶端
from socket import *
c=socket(AF_INET,SOCK_STREAM)
c.connect(('127.0.0.1',8080))

while True:
    msg=input('>>: ').strip()
    if not msg:continue
    c.send(msg.encode('utf-8'))
    data=c.recv(1024)
    print(data.decode('utf-8'))

c.close()
#服務端
from
multiprocessing import Pool import os from socket import * s=socket(AF_INET,SOCK_STREAM) s.setsockopt(SOL_SOCKET,SO_REUSEADDR,1) s.bind(('127.0.0.1',8080)) s.listen(5) def talK(conn,addr): print(os.getpid()) while True: try: data=conn.recv(1024) if not data:break conn.send(data.upper()) except Exception: break conn.close() if __name__ == '__main__': p=Pool(4) while True: conn,addr=s.accept() p.apply_async(talK,args=(conn,addr)) s.close()

 

 
       


免責聲明!

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



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