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

溫馨提示×

溫馨提示×

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

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

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

發布時間:2021-07-10 15:59:12 來源:億速云 閱讀:144 作者: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

上述內容就是Python中怎么利用Asyncio實現異步編程,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

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

AI

额敏县| 平塘县| 元朗区| 鄂尔多斯市| 庐江县| 阿城市| 图木舒克市| 额尔古纳市| 津南区| 南雄市| 平乡县| 灵台县| 朝阳市| 宜都市| 榆林市| 孟连| 滁州市| 柳州市| 甘孜| 丹东市| 界首市| 佛山市| 始兴县| 马尔康县| 紫阳县| 梅州市| 仙桃市| 花垣县| 沙洋县| 万荣县| 巍山| 深圳市| 合肥市| 墨江| 黔江区| 河南省| 绥芬河市| 玉屏| 舟山市| 廉江市| 四川省|