最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python通過(guò)future處理并發(fā)問(wèn)題

 更新時(shí)間:2017年10月17日 08:34:26   作者:python修行路  
這篇文章主要介紹了Python通過(guò)future處理并發(fā)問(wèn)題,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下

future初識(shí)

通過(guò)下面腳本來(lái)對(duì)future進(jìn)行一個(gè)初步了解:

例子1:普通通過(guò)循環(huán)的方式

import os
import time
import sys
import requests
POP20_CC = (
 "CN IN US ID BR PK NG BD RU JP MX PH VN ET EG DE IR TR CD FR"
).split()
BASE_URL = 'http://flupy.org/data/flags'
DEST_DIR = 'downloads/'
def save_flag(img,filename):
 path = os.path.join(DEST_DIR,filename)
 with open(path,'wb') as fp:
 fp.write(img)
def get_flag(cc):
 url = "{}/{cc}/{cc}.gif".format(BASE_URL,cc=cc.lower())
 resp = requests.get(url)
 return resp.content
def show(text):
 print(text,end=" ")
 sys.stdout.flush()
def download_many(cc_list):
 for cc in sorted(cc_list):
 image = get_flag(cc)
 show(cc)
 save_flag(image,cc.lower()+".gif")
 return len(cc_list)
def main(download_many):
 t0 = time.time()
 count = download_many(POP20_CC)
 elapsed = time.time()-t0
 msg = "\n{} flags downloaded in {:.2f}s"
 print(msg.format(count,elapsed))
if __name__ == '__main__':
 main(download_many)

    例子2:通過(guò)future方式實(shí)現(xiàn),這里對(duì)上面的部分代碼進(jìn)行了復(fù)用

 from concurrent import futures
from flags import save_flag, get_flag, show, main
MAX_WORKERS = 20
def download_one(cc):
 image = get_flag(cc)
 show(cc)
 save_flag(image, cc.lower()+".gif")
 return cc
def download_many(cc_list):
 workers = min(MAX_WORKERS,len(cc_list))
 with futures.ThreadPoolExecutor(workers) as executor:
 res = executor.map(download_one, sorted(cc_list))
 return len(list(res))
if __name__ == '__main__':
 main(download_many)

    分別運(yùn)行三次,兩者的平均速度:13.67和1.59s,可以看到差別還是非常大的。

future

future是concurrent.futures模塊和asyncio模塊的重要組件

從python3.4開(kāi)始標(biāo)準(zhǔn)庫(kù)中有兩個(gè)名為Future的類:concurrent.futures.Future和asyncio.Future
這兩個(gè)類的作用相同:兩個(gè)Future類的實(shí)例都表示可能完成或者尚未完成的延遲計(jì)算。與Twisted中的Deferred類、Tornado框架中的Future類的功能類似

注意:通常情況下自己不應(yīng)該創(chuàng)建future,而是由并發(fā)框架(concurrent.futures或asyncio)實(shí)例化

原因:future表示終將發(fā)生的事情,而確定某件事情會(huì)發(fā)生的唯一方式是執(zhí)行的時(shí)間已經(jīng)安排好,因此只有把某件事情交給concurrent.futures.Executor子類處理時(shí),才會(huì)創(chuàng)建concurrent.futures.Future實(shí)例。
如:Executor.submit()方法的參數(shù)是一個(gè)可調(diào)用的對(duì)象,調(diào)用這個(gè)方法后會(huì)為傳入的可調(diào)用對(duì)象排定時(shí)間,并返回一個(gè)

future

客戶端代碼不能應(yīng)該改變future的狀態(tài),并發(fā)框架在future表示的延遲計(jì)算結(jié)束后會(huì)改變期物的狀態(tài),我們無(wú)法控制計(jì)算何時(shí)結(jié)束。

這兩種future都有.done()方法,這個(gè)方法不阻塞,返回值是布爾值,指明future鏈接的可調(diào)用對(duì)象是否已經(jīng)執(zhí)行。客戶端代碼通常不會(huì)詢問(wèn)future是否運(yùn)行結(jié)束,而是會(huì)等待通知。因此兩個(gè)Future類都有.add_done_callback()方法,這個(gè)方法只有一個(gè)參數(shù),類型是可調(diào)用的對(duì)象,future運(yùn)行結(jié)束后會(huì)調(diào)用指定的可調(diào)用對(duì)象。

.result()方法是在兩個(gè)Future類中的作用相同:返回可調(diào)用對(duì)象的結(jié)果,或者重新拋出執(zhí)行可調(diào)用的對(duì)象時(shí)拋出的異常。但是如果future沒(méi)有運(yùn)行結(jié)束,result方法在兩個(gè)Futrue類中的行為差別非常大。

對(duì)concurrent.futures.Future實(shí)例來(lái)說(shuō),調(diào)用.result()方法會(huì)阻塞調(diào)用方所在的線程,直到有結(jié)果可返回,此時(shí),result方法可以接收可選的timeout參數(shù),如果在指定的時(shí)間內(nèi)future沒(méi)有運(yùn)行完畢,會(huì)拋出TimeoutError異常。

而asyncio.Future.result方法不支持設(shè)定超時(shí)時(shí)間,在獲取future結(jié)果最好使用yield from結(jié)構(gòu),但是concurrent.futures.Future不能這樣做

不管是asyncio還是concurrent.futures.Future都會(huì)有幾個(gè)函數(shù)是返回future,其他函數(shù)則是使用future,在最開(kāi)始的例子中我們使用的Executor.map就是在使用future,返回值是一個(gè)迭代器,迭代器的__next__方法調(diào)用各個(gè)future的result方法,因此我們得到的是各個(gè)futrue的結(jié)果,而不是future本身

關(guān)于future.as_completed函數(shù)的使用,這里我們用了兩個(gè)循環(huán),一個(gè)用于創(chuàng)建并排定future,另外一個(gè)用于獲取future的結(jié)果

from concurrent import futures
from flags import save_flag, get_flag, show, main
MAX_WORKERS = 20
def download_one(cc):
 image = get_flag(cc)
 show(cc)
 save_flag(image, cc.lower()+".gif")
 return cc
def download_many(cc_list):
 cc_list = cc_list[:5]
 with futures.ThreadPoolExecutor(max_workers=3) as executor:
 to_do = []
 for cc in sorted(cc_list):
  future = executor.submit(download_one,cc)
  to_do.append(future)
  msg = "Secheduled for {}:{}"
  print(msg.format(cc,future))
 results = []
 for future in futures.as_completed(to_do):
  res = future.result()
  msg = "{}result:{!r}"
  print(msg.format(future,res))
  results.append(res)
 return len(results)
if __name__ == '__main__':
 main(download_many)

    結(jié)果如下:

注意:Python代碼是無(wú)法控制GIL,標(biāo)準(zhǔn)庫(kù)中所有執(zhí)行阻塞型IO操作的函數(shù),在等待操作系統(tǒng)返回結(jié)果時(shí)都會(huì)釋放GIL.運(yùn)行其他線程執(zhí)行,也正是因?yàn)檫@樣,Python線程可以在IO密集型應(yīng)用中發(fā)揮作用

以上都是concurrent.futures啟動(dòng)線程,下面通過(guò)它啟動(dòng)進(jìn)程

concurrent.futures啟動(dòng)進(jìn)程

concurrent.futures中的ProcessPoolExecutor類把工作分配給多個(gè)Python進(jìn)程處理,因此,如果需要做CPU密集型處理,使用這個(gè)模塊能繞開(kāi)GIL,利用所有的CPU核心。

其原理是一個(gè)ProcessPoolExecutor創(chuàng)建了N個(gè)獨(dú)立的Python解釋器,N是系統(tǒng)上面可用的CPU核數(shù)。

使用方法和ThreadPoolExecutor方法一樣

總結(jié)

相關(guān)文章

  • Python隨機(jī)數(shù)種子(random seed)的使用

    Python隨機(jī)數(shù)種子(random seed)的使用

    在科學(xué)技術(shù)和機(jī)器學(xué)習(xí)等其他算法相關(guān)任務(wù)中,我們經(jīng)常需要用到隨機(jī)數(shù),本文就詳細(xì)的介紹一下Python隨機(jī)數(shù)種子,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Python開(kāi)發(fā)游戲自動(dòng)化后臺(tái)腳本的實(shí)現(xiàn)

    Python開(kāi)發(fā)游戲自動(dòng)化后臺(tái)腳本的實(shí)現(xiàn)

    本文主要介紹了Python開(kāi)發(fā)游戲自動(dòng)化后臺(tái)腳本的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • python中的內(nèi)置函數(shù)getattr()介紹及示例

    python中的內(nèi)置函數(shù)getattr()介紹及示例

    其實(shí)getattr()這個(gè)方法最主要的作用是實(shí)現(xiàn)反射機(jī)制。也就是說(shuō)可以通過(guò)字符串獲取方法實(shí)例。這樣,你就可以把一個(gè)類可能要調(diào)用的方法放在配置文件里,在需要的時(shí)候動(dòng)態(tài)加載。
    2014-07-07
  • Python程序退出方式小結(jié)

    Python程序退出方式小結(jié)

    這篇文章主要介紹了Python程序退出方式小結(jié),具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-12-12
  • Python?OpenCV實(shí)現(xiàn)圖形檢測(cè)示例詳解

    Python?OpenCV實(shí)現(xiàn)圖形檢測(cè)示例詳解

    圖形檢測(cè)在計(jì)算機(jī)視覺(jué)開(kāi)發(fā)中是一項(xiàng)非常重要的操作,算法通過(guò)對(duì)圖像的檢測(cè),分析出圖像中可能存在哪些形狀。本文詳細(xì)介紹了Python+OpenCV如何實(shí)現(xiàn)圖形檢測(cè),感興趣的可以了解一下
    2022-04-04
  • 十個(gè)簡(jiǎn)單使用的Python自動(dòng)化腳本分享

    十個(gè)簡(jiǎn)單使用的Python自動(dòng)化腳本分享

    今天小編給大家分享10個(gè)Python高級(jí)腳本,幫助我們減少無(wú)謂的時(shí)間浪費(fèi),提高工作學(xué)習(xí)中的效率。文中示例代碼講解詳細(xì),需要的可以參考一下
    2022-05-05
  • pycharm激活碼快速激活及使用步驟

    pycharm激活碼快速激活及使用步驟

    這篇文章主要介紹了pycharm激活碼快速激活及使用步驟,本文分步驟給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • Python 基于wxpy庫(kù)實(shí)現(xiàn)微信添加好友功能(簡(jiǎn)潔)

    Python 基于wxpy庫(kù)實(shí)現(xiàn)微信添加好友功能(簡(jiǎn)潔)

    這篇文章主要介紹了Python 基于wxpy庫(kù)實(shí)現(xiàn)微信添加好友功能,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Python3讀取文件常用方法實(shí)例分析

    Python3讀取文件常用方法實(shí)例分析

    這篇文章主要介紹了Python3讀取文件常用方法,以實(shí)例形式較為詳細(xì)的分析了Python一次性讀取、逐行讀取及讀取文件一部分的實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-05-05
  • python基于pyppeteer制作PDF文件

    python基于pyppeteer制作PDF文件

    這篇文章主要介紹了python基于pyppeteer制作PDF文件的方法,幫助大家更好的理解和學(xué)習(xí)使用python,感興趣的朋友可以了解下
    2021-03-03

最新評(píng)論

东宁县| 班戈县| 江达县| 河南省| 台南县| 永安市| 无为县| 三明市| 成安县| 中超| 库尔勒市| 汶川县| 马龙县| 吉首市| 千阳县| 延安市| 商河县| 安泽县| 贺州市| 龙门县| 宝清县| 左贡县| 友谊县| 贺兰县| 吉林省| 秭归县| 施甸县| 手游| 泗水县| 庆阳市| 大城县| 乳山市| 陕西省| 定结县| 怀安县| 肇源县| 江都市| 宿松县| 石城县| 民县| 灵璧县|