日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python协程等待执行完成_异步等待的 Python 协程

發布時間:2024/3/24 python 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python协程等待执行完成_异步等待的 Python 协程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

現在 Python 已經支持用協程進行異步處理。但最近有建議稱添加協程以全面完善 Python 的語言結構,而不是像現在這樣把他們作為生成器的一個類型。此外,兩個新的關鍵字———異步(async)和等待(await),都該添加到 Python 中來支持協程。

也許有人不太了解協程,其實協程的原理很簡單,打個比方就能講明白了:假設有十個人去食堂打飯,這個食堂比較窮,只有一個打飯窗口和一個打飯阿姨,那么打飯就只能一個一個排隊進行。這十個人胃口很大,每個人都要點5個菜,但這十個人都喜歡猶豫不決,點菜的時候每點一個菜后再想下一個菜點什么,因此后面的人等得很著急呀。

這樣一直站著也不是個事兒,所以打菜的阿姨看到某人猶豫5秒后就會吼一聲,讓他排到隊伍末尾,讓別人先打菜,等輪到他的時候他也差不多想好吃什么了。這確實是個不錯的方法,但也有一個缺點,那就是打菜的阿姨會等每個人5秒鐘,如果那個人在5秒內沒有做出決定吃啥,其實這5秒就浪費了。一個人點一個菜就是浪費5秒,十個人每個人點5個菜可就浪費的多啦「菜都涼了要」。

那怎么辦呢?阿姨又發話了:大家都是學生,學生就要自覺,我以后也不主動讓你們排到末尾了,如果你們覺得自己會猶豫不決,就主動點直接點一個菜就站后面去,等下次排到的時候也差不多想好吃啥了。

這個方法果然有效,大家點了菜后想的第一件事情不是下一個菜吃什么,而是自己會不會猶豫,如果會猶豫那直接排到隊伍后面去,如果不會就接著點菜。這樣一來整個隊伍的效率自然就高了。

這個例子里,排隊阿姨的那聲吼就是我們的 CPU 中斷,用于切換上下文。每個打飯的學生就是一個 task。而每個人決定自己要不要讓出窗口的這種行為,其實就是我們協程的核心思想。

OK,回到主題,協程就是一種可以在代碼的各種預定義位置暫停和恢復執行的函數,它避免了無意義的調度,由此提高代碼性能。而子程序是一種特殊的協同程序,它只有單一入口,通過回調來完成執行。Python 的協程「現有的以生成器為基礎的協程和新提出的協程」不是一般意義上的協程,因為在執行暫停時它們只能將控制權轉給調用者,而不是像常見的那樣將控制權轉給別的協程。輔之以事件循環,協程可用于異步處理,尤其是在 I / O 中。

Python 當前支持的協程基于 PEP342 增強型生成器,于 Python 2.5 版本開始采用。該 PEP 將 yield 語句改為表達式,并為生成器增加了一些新的方法 「 send() , throw() , and close() 」 ,同時確保 close() 方法在生成器進入垃圾回收階段時得到調用。該功能在 Python 3.3 版本的 PEP 380 中得到進一步增強,它通過增加 yield 表達式,允許生成器將部分功能授予另一個生成器「即子生成器」。

以上方法都使協程依賴于生成器,這使得在代碼段何處進行異步調用變得令人困惑,且頗受限制。尤其,with 和 for 聲明在理論上可以將協程用于異步調用,但 Python 語法在那些位置不允許使用 yield 表達式,因此無法進行異步調用。此外,如果協程的重構將 yield 或 yield from 從函數中移除 ,它就不再被視為協程,這會導致一些不明顯的錯誤; asyncio 模塊通過 @asyncio.coroutine裝飾器來彌補這方面的不足。

PEP 492 旨在解決以上所有問題。其想法源于 Yury Selivanov 在四月中旬提出的 python-ideas 郵件列表,該想法受到很多人熱情追捧。在5月5日,Guido van Rossum 同意將它添加在 Python 3.5 版本中。不僅如此,5月12日就得到執行。一切都進展迅速,盡管最終該方法還是在 python-idea 和 python-dev 方面引起熱情討論。

從語法角度看,變化相當簡單:

async def read_data(db):

data = await db.fetch('SELECT ...')

...

這個例子「來源于 PEP」將使用新的 async def 構造函數創建一個 read_data() 協程。 await 表達式將暫停執行 read_data(),直到 db.fetch() await able 完成并返回其結果。await 類似于 yeild from ,但它會確保其參數 awaitable。

此外還有幾種不同類型的 awaitable。一種是本地的協程對象,在調用本地協同程序后的返回為 awaitable,還有基于生成器且有 @types.coroutine 裝飾的協程。還有一種是未來對象,它代表著在未來完成的操作,也是 awaitable。__await __()方法在 awaitable 的對象都會出現。

然而,向一種語言添加新的關鍵字時會出現這樣的問題:任何與關鍵字名字相同的變量都會成為語法錯誤。為了避免該問題,Python 3.5 和 3.6 版本將 “softly deprecate “ 「溫柔棄用」 async 和 wait 為變量名,而不將他們當做語法錯誤。解析器會跟蹤 async def 塊,并將塊內的關鍵字區別對待,從而使現有的使用繼續有效。

新的特性中,異步還有兩種新用途:異步內容管理器(with)和迭代器(for)。在協程里,這兩種構造函數的示例如下:

async def commit(session, data):

...

async with session.transaction():

...

await session.update(data)

...

...

async for row in Cursor():

print(row)

異步內容管理器必須實現兩個異步方法,__aenter __()和__aexit __(),他們都返回 awaitables;異步迭代器須實現__aiter __()和__anext __()。這些方法都是現有的同步內容管理器和迭代器的異步版本。

此前主要的討論是延期執行的 “cofunction” 功能 PEP 3152 是否會是更好的起點,該 PEP 的作者 Greg Ewing 提出了此問題。但有很多人認為 Selivanov 提議的語法更適合 codef,cocall ,也有人更加贊同 Ewing 的提議。這樣來來回回的爭論了很多次。有一些人認為cofunction 的語法在處理某些情況時相當復雜并且不符合 Python 語言的特性。后來 Van Rossum 總結了 cofunctions 語法存在的問題,并拒絕采納該方法。

此外,還有幾點關于附加異步功能的建議值得討論,但并不緊急。對于關鍵詞的討論有些本末倒置。 await 的優先級問題也討論了一段時間,結果是,不同于 yeild 和 yeild from 僅有最低優先級,await 具有較高的優先級。

但 Mark Shannon 抱怨說,實現 Selivanov 的建議并不需要增加新的語法。其他人也提出了類似的意見,但 Selivanov 或其他支持者并未對此提出反駁。關鍵在于簡化協同程序的編寫。除此之外,Van Rossum 希望協同程序暫停的位置能夠顯而易見,查看代碼就能發現:

新的語法才是 PEP 存在的意義。我希望通過句法結構就能判斷出協程的懸停點。

在兩三周后,發布了多個版本的 PEP ,引起了諸多辯論。Selivanov 耐心地解釋他的想法,并根據反饋意見不斷修正自己的想法。異步協程特性對 Python 語言的未來很可能至關重要,整個探索過程都很快,很順遂。不過,Python 開發者們將這些想法付諸實踐很可能還需要一段時間。

本文系 OneAPM 工程師翻譯。OneAPM 是應用性能管理領域的新興領軍企業,能幫助企業用戶和開發者輕松實現:緩慢的程序代碼和 SQL 語句的實時抓取。想技術文章,請訪問 OneAPM 官方博客。

總結

以上是生活随笔為你收集整理的python协程等待执行完成_异步等待的 Python 协程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。