摘要:并發(fā)的方式有多種,多線程,多進(jìn)程,異步等。多線程和多進(jìn)程之間的場景切換和通訊代價很高,不適合密集型的場景關(guān)于多線程和多進(jìn)程的特點已經(jīng)超出本文討論的范疇,有興趣的同學(xué)可以自行搜索深入理解。
編程中,我們經(jīng)常會遇到“并發(fā)”這個概念,目的是讓軟件能充分利用硬件資源,提高性能。并發(fā)的方式有多種,多線程,多進(jìn)程,異步IO等。多線程和多進(jìn)程更多應(yīng)用于CPU密集型的場景,比如科學(xué)計算的時間都耗費在CPU上,利用多核CPU來分擔(dān)計算任務(wù)。多線程和多進(jìn)程之間的場景切換和通訊代價很高,不適合IO密集型的場景(關(guān)于多線程和多進(jìn)程的特點已經(jīng)超出本文討論的范疇,有興趣的同學(xué)可以自行搜索深入理解)。而異步IO就是非常適合IO密集型的場景,比如網(wǎng)絡(luò)爬蟲和Web服務(wù)。
在計算機程序中,IO就是讀寫磁盤、讀寫網(wǎng)絡(luò)的操作,這種讀寫速度比讀寫內(nèi)存、CPU緩存慢得多,前者的耗時是后者的成千上萬倍甚至更多。這就導(dǎo)致,IO密集型的場景99%以上的時間都花費在IO等待的時間上。異步IO就是把CPU從漫長的等待中解放出來的方法。這就可以大大提高我們寫的軟件系統(tǒng)的并發(fā)性。這樣的軟件,可以是網(wǎng)絡(luò)爬蟲,也可以是Web服務(wù)等一切IO密集型的系統(tǒng)。
異步IO的優(yōu)勢顯而易見,各種語言都通過實現(xiàn)這個機制來提高自身的效率,Python也不例外。Python經(jīng)歷了2和3兩個大版本的躍遷。這其中也有對異步IO支持的變化歷程。
Python 2的異步IO庫Python 2 時代官方并沒有異步IO的支持,但是有幾個第三方庫通過事件或事件循環(huán)(Event Loop)實現(xiàn)了異步IO,它們是:
twisted: 是事件驅(qū)動的網(wǎng)絡(luò)庫
gevent: greenlet + libevent(后來是libev或libuv)。通過協(xié)程(greenlet)和事件循環(huán)庫(libev,libuv)實現(xiàn)的gevent使用很廣泛。
tornado: 支持異步IO的web框架。自己實現(xiàn)了IOLOOP。
Python 3 官方的異步IOPython 3.4 加入了asyncio 庫,使得Python有了支持異步IO的官方庫。這個庫,底層是事件循環(huán)(EventLoop),上層是協(xié)程和任務(wù)。asyncio自從3.4 版本加入到最新的 3.7版一直在改進(jìn)中。
Python 3.4 剛開始的asyncio的協(xié)程還是基于生成器的,通過 yield from 語法實現(xiàn),可以通過裝飾器 @asyncio.coroutine (已過時)裝飾一個函數(shù)來定義一個協(xié)程。比如:
Python 3.5 引入了兩個新的關(guān)鍵字 await 和 async 用來替換 @asyncio.coroutine 和 yield from ,從語言本身來支持異步IO。從而使得異步編程更加簡潔,并和普通的生成器區(qū)別開來。
注意: 對基于生成器的協(xié)程的支持已棄用,并計劃在 Python 3.10 中移除。所以,寫異步IO程序時只需使用 async 和 await 即可。
Python 3.7 又進(jìn)行了優(yōu)化,把API分組為高層級API和低層級API。 我們先看看下面的代碼,發(fā)現(xiàn)與上面的有什么不同?
除了用 async 替換 @asyncio.coroutine 和用 await 替換 yield from 外,最大的變化就是關(guān)于eventloop的代碼不見了,只有一個 async.run()。這就是 3.7 的改進(jìn),把eventloop相關(guān)的API歸入到低層級API,新引進(jìn)run()作為高層級API讓寫應(yīng)用程序的開發(fā)者調(diào)用,而不用再關(guān)心eventloop。除非你要寫異步庫(比如MySQL異步庫)才會和eventloop打交道。
需要注意的是, async.run() 是3.7版新增加的,處于暫定API狀態(tài)。 暫定API,是指被有意排除在標(biāo)準(zhǔn)庫的向后兼容性保證之外的應(yīng)用編程接口。雖然此類接口通常不會再有重大改變,但只要其被標(biāo)記為暫定,就可能在核心開發(fā)者確定有必要的情況下進(jìn)行向后不兼容的更改(甚至包括移除該接口)。此種更改并不會隨意進(jìn)行 — 僅在 API 被加入之前未考慮到的嚴(yán)重基礎(chǔ)性缺陷被發(fā)現(xiàn)時才可能會這樣做。即便是對暫定 API 來說,向后不兼容的更改也會被視為“最后的解決方案” —— 任何問題被確認(rèn)時都會盡可能先嘗試找到一種向后兼容的解決方案。這種處理過程允許標(biāo)準(zhǔn)庫持續(xù)不斷地演進(jìn),不至于被有問題的長期性設(shè)計缺陷所困。
從上面關(guān)于 asyncio 的發(fā)展來看它一直在變化,3.4,3.5,3.6, 3.7 都有很多細(xì)節(jié)上的變化。當(dāng)我看到3.7的run()函數(shù)時,也發(fā)現(xiàn)一年前基于3.6的asnycio寫的爬蟲不那么優(yōu)雅了。
這種變化,一方面改善了asyncio本身的性能和使用方便程度,但另一方面也增加了我們使用者的學(xué)習(xí)成本、Python升級帶來的改造的成本。如果你以消極的態(tài)度抵制這種變化,可以去學(xué)習(xí)golang,C++來實現(xiàn)你的程序;如果你以積極的態(tài)度迎接這種變化,可以更快的掌握這種變化,并優(yōu)雅 高效的實現(xiàn)你的程序。
只要你喜歡用Python寫程序解決問題,那么就接受并掌握這種變化吧。其實,那種語言不在變,那種技術(shù)不在前進(jìn)。作為程序員,你只有不斷地學(xué)習(xí)和前進(jìn)。
uvloopuvloop是用Cython寫的,基于libuv這個C語言實現(xiàn)的高性能異步I/O庫。asyncio自己的事件循環(huán)是用Python寫的,用uvloop替換asyncio自己的事件循環(huán)可以是asyncio的速度更快。并且使用相當(dāng)簡潔:
大家在學(xué)python的時候肯定會遇到很多難題,以及對于新技術(shù)的追求,這里推薦一下我們的Python學(xué)習(xí)扣qun:784758214,這里是python學(xué)習(xí)者聚集地!!同時,自己是一名高級python開發(fā)工程師,從基礎(chǔ)的python腳本到web開發(fā)、爬蟲、django、數(shù)據(jù)挖掘等,零基礎(chǔ)到項目實戰(zhàn)的資料都有整理。送給每一位python的小伙伴!每日分享一些學(xué)習(xí)的方法和需要注意的小細(xì)節(jié)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/43839.html
摘要:具有以下基本同步原語子進(jìn)程提供了通過創(chuàng)建和管理子進(jìn)程的。雖然隊列不是線程安全的,但它們被設(shè)計為專門用于代碼。表示異步操作的最終結(jié)果。 Python的asyncio是使用 async/await 語法編寫并發(fā)代碼的標(biāo)準(zhǔn)庫。通過上一節(jié)的講解,我們了解了它不斷變化的發(fā)展歷史。到了Python最新穩(wěn)定版 3.7 這個版本,asyncio又做了比較大的調(diào)整,把這個庫的API分為了 高層級API和...
摘要:創(chuàng)建第一個協(xié)程推薦使用語法來聲明協(xié)程,來編寫異步應(yīng)用程序。協(xié)程兩個緊密相關(guān)的概念是協(xié)程函數(shù)通過定義的函數(shù)協(xié)程對象調(diào)用協(xié)程函數(shù)返回的對象。它是一個低層級的可等待對象,表示一個異步操作的最終結(jié)果。 我們講以Python 3.7 上的asyncio為例講解如何使用Python的異步IO。 showImg(https://segmentfault.com/img/remote/14600000...
摘要:理解迭代對象迭代器生成器后端掘金本文源自作者的一篇博文,原文是,俺寫的這篇文章是按照自己的理解做的參考翻譯。比較的是兩個對象的內(nèi)容是后端掘金黑魔法之協(xié)程異步后端掘金本文為作者原創(chuàng),轉(zhuǎn)載請先與作者聯(lián)系。 完全理解關(guān)鍵字with與上下文管理器 - 掘金如果你有閱讀源碼的習(xí)慣,可能會看到一些優(yōu)秀的代碼經(jīng)常出現(xiàn)帶有 with 關(guān)鍵字的語句,它通常用在什么場景呢?今天就來說說 with 和 上下...
摘要:前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點分為新聞熱點開發(fā)教程工程實踐深度閱讀開源項目巔峰人生等欄目。背后的故事本文是對于年之間世界發(fā)生的大事件的詳細(xì)介紹,闡述了從提出到角力到流產(chǎn)的前世今生。 前端每周清單專注前端領(lǐng)域內(nèi)容,以對外文資料的搜集為主,幫助開發(fā)者了解一周前端熱點;分為新聞熱點、開發(fā)教程、工程實踐、深度閱讀、開源項目、巔峰人生等欄目。歡迎...
閱讀 1952·2021-09-28 09:36
閱讀 2519·2021-09-08 09:35
閱讀 3122·2019-08-30 15:53
閱讀 1608·2019-08-30 14:08
閱讀 727·2019-08-29 18:40
閱讀 2918·2019-08-29 13:57
閱讀 2759·2019-08-29 13:55
閱讀 748·2019-08-26 13:45