中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Python 中怎么使用Asyncio實現異步編程

發布時間:2021-07-05 17:19:35 來源:億速云 閱讀:135 作者:Leah 欄目:編程語言

Python 中怎么使用Asyncio實現異步編程,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

異步是怎么一回事?

在傳統的順序編程中, 所有發送給解釋器的指令會一條條被執行。此類代碼的輸出容易顯現和預測。 但是…

譬如說你有一個腳本向3個不同服務器請求數據。  有時,誰知什么原因,發送給其中一個服務器的請求可能意外地執行了很長時間。想象一下從第二個服務器獲取數據用了10秒鐘。在你等待的時候,整個腳本實際上什么也沒干。如果你可以寫一個腳本可以不去等待第二個請求而是僅僅跳過它,然后開始執行第三個請求,然后回到第二個請求,執行之前離開的位置會怎么樣呢。就是這樣。你通過切換任務最小化了空轉時間。盡管如此,當你需要一個幾乎沒有I/O的簡單腳本時,你不想用異步代碼。

還有一件重要的事情要提,所有代碼在一個線程中運行。所以如果你想讓程序的一部分在后臺執行同時干一些其他事情,那是不可能的。

準備開始

這是 asyncio 主概念最基本的定義:

  • 協程— 消費數據的生成器,但是不生成數據。Python 2.5 介紹了一種新的語法讓發送數據到生成器成為可能。我推薦查閱David Beazley “A  Curious Course on Coroutines and Concurrency” 關于協程的詳細介紹。

  • 任務— 協程調度器。如果你觀察下面的代碼,你會發現它只是讓 event_loop 盡快調用它的_step ,同時 _step  只是調用協程的下一步。

class Task(futures.Future):       def __init__(self, coro, loop=None):         super().__init__(loop=loop)         ...         self._loop.call_soon(self._step)      def _step(self):             ...         try:             ...             result = next(self._coro)         except StopIteration as exc:             self.set_result(exc.value)         except BaseException as exc:             self.set_exception(exc)             raise         else:             ...             self._loop.call_soon(self._step)
  • 事件循環— 把它想成 asyncio 的中心執行器。

現在我們看一下所有這些如何融為一體。正如我之前提到的,異步代碼在一個線程中運行。

Python 中怎么使用Asyncio實現異步編程

從上圖可知:

1.消息循環是在線程中執行

2.從隊列中取得任務

3.每個任務在協程中執行下一步動作

4.如果在一個協程中調用另一個協程(await  <coroutine_name>),會觸發上下文切換,掛起當前協程,并保存現場環境(變量,狀態),然后載入被調用協程

5.如果協程的執行到阻塞部分(阻塞I/O,Sleep),當前協程會掛起,并將控制權返回到線程的消息循環中,然后消息循環繼續從隊列中執行下一個任務...以此類推

6.隊列中的所有任務執行完畢后,消息循環返回***個任務

異步和同步的代碼對比

現在我們實際驗證異步模式的切實有效,我會比較兩段 python 腳本,這兩個腳本除了 sleep 方法外,其余部分完全相同。在***個腳本里,我會用標準的  time.sleep 方法,在第二個腳本里使用 asyncio.sleep 的異步方法。

這里使用 Sleep 是因為它是一個用來展示異步方法如何操作 I/O 的最簡單辦法。

使用同步 sleep 方法的代碼:

import asyncio   import time   from datetime import datetime   async def custom_sleep():       print('SLEEP', datetime.now())     time.sleep(1)  async def factorial(name, number):       f = 1     for i in range(2, number+1):         print('Task {}: Compute factorial({})'.format(name, i))         await custom_sleep()         f *= i     print('Task {}: factorial({}) is {}\n'.format(name, number, f))   start = time.time()   loop = asyncio.get_event_loop()  tasks = [       asyncio.ensure_future(factorial("A", 3)),     asyncio.ensure_future(factorial("B", 4)), ] loop.run_until_complete(asyncio.wait(tasks))   loop.close()  end = time.time()   print("Total time: {}".format(end - start))

腳本輸出:

Task A: Compute factorial(2)   SLEEP 2017-04-06 13:39:56.207479   Task A: Compute factorial(3)   SLEEP 2017-04-06 13:39:57.210128   Task A: factorial(3) is 6  Task B: Compute factorial(2)   SLEEP 2017-04-06 13:39:58.210778   Task B: Compute factorial(3)   SLEEP 2017-04-06 13:39:59.212510   Task B: Compute factorial(4)   SLEEP 2017-04-06 13:40:00.217308   Task B: factorial(4) is 24  Total time: 5.016386032104492

使用異步 Sleep 的代碼:

import asyncio   import time   from datetime import datetime   async def custom_sleep():       print('SLEEP {}\n'.format(datetime.now()))     await asyncio.sleep(1)  async def factorial(name, number):       f = 1     for i in range(2, number+1):         print('Task {}: Compute factorial({})'.format(name, i))         await custom_sleep()         f *= i     print('Task {}: factorial({}) is {}\n'.format(name, number, f))   start = time.time()   loop = asyncio.get_event_loop()  tasks = [       asyncio.ensure_future(factorial("A", 3)),     asyncio.ensure_future(factorial("B", 4)), ] loop.run_until_complete(asyncio.wait(tasks))   loop.close()  end = time.time()   print("Total time: {}".format(end - start))

腳本輸出:

Task A: Compute factorial(2)   SLEEP 2017-04-06 13:44:40.648665  Task B: Compute factorial(2)   SLEEP 2017-04-06 13:44:40.648859  Task A: Compute factorial(3)   SLEEP 2017-04-06 13:44:41.649564  Task B: Compute factorial(3)   SLEEP 2017-04-06 13:44:41.649943  Task A: factorial(3) is 6  Task B: Compute factorial(4)   SLEEP 2017-04-06 13:44:42.651755  Task B: factorial(4) is 24  Total time: 3.008226156234741

從輸出可以看到,異步模式的代碼執行速度快了大概兩秒。當使用異步模式的時候(每次調用 await asyncio.sleep(1)  ),進程控制權會返回到主程序的消息循環里,并開始運行隊列的其他任務(任務A或者任務B)。

關于Python 中怎么使用Asyncio實現異步編程問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

玛纳斯县| 密云县| 唐山市| 岐山县| 泸水县| 阿坝| 翁牛特旗| 江陵县| 阳原县| 杂多县| 盈江县| 同江市| 荥经县| 珲春市| 岐山县| 泾川县| 吴川市| 靖边县| 九台市| 阿拉善左旗| 宜兰县| 韶山市| 门源| 江华| 张家港市| 乐昌市| 台州市| 兴山县| 青冈县| 永新县| 凤台县| 凉城县| 盐池县| 麻城市| 宜昌市| 阿鲁科尔沁旗| 武夷山市| 宕昌县| 尤溪县| 易门县| 来宾市|