Python系列之程序池與執行緒池
阿新 • • 發佈:2018-12-31
在剛開始學多程序或多執行緒時,我們迫不及待地基於多程序或多執行緒實現併發的套接字通訊,然而這種實現方式的致命缺陷是:服務的開啟的程序數或執行緒數都會隨著併發的客戶端數目地增多而增多,這會對服務端主機帶來巨大的壓力,甚至於不堪重負而癱瘓,於是我們必須對服務端開啟的程序數或執行緒數加以控制,讓機器在一個自己可以承受的範圍內執行,這就是程序池或執行緒池的用途,例如程序池,就是用來存放程序的池子,本質還是基於多程序,只不過是對開啟程序的數目加上了限制
程序池
不說了,直接上程式碼:
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
import os,time,random
def task(n):
print('%s is runing' %os.getpid())
time.sleep(random.randint(1,3))
return n**2
if __name__ == '__main__':
executor=ProcessPoolExecutor(max_workers=3)
futures=[]
for i in range(11):
future=executor.submit(task,i)
futures.append(future)
executor.shutdown(True )
print('+++>')
for future in futures:
print(future.result())
執行緒池
把ProcessPoolExecutor換成ThreadPoolExecutor,其餘用法全部相同
回撥函式
from concurrent.futures import ThreadPoolExecutor,ProcessPoolExecutor
from multiprocessing import Pool
import requests
import json
import os
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(res):
res=res.result()
print('<程序%s> parse %s' %(os.getpid(),res['url']))
parse_res='url:<%s> size:[%s]\n' %(res['url'],len(res['text']))
with open('db.txt','a') as f:
f.write(parse_res)
if __name__ == '__main__':
urls=[
'https://www.baidu.com',
'https://www.python.org',
'https://www.openstack.org',
'https://help.github.com/',
'http://www.sina.com.cn/'
]
p=ProcessPoolExecutor(3)
for url in urls:
p.submit(get_page,url).add_done_callback(parse_page) #parse_page拿到的是一個future物件obj,需要用obj.result()拿到結果