簡體   English   中英

什么時候不使用asyncio有意義?

[英]When would not using asyncio make sense?

在什么情況下,一個線程或執行者(使用線程)會通過asyncio

隨着我使用Python(CPython)的經驗的進步,它集中於優化工作腳本以批量執行某種形式的Web服務調用並處理響應。 但是,經過幾代腳本構建之后,我發現自己想知道為什么我不使用最新版本?

請允許我在下面提供一些背景信息...

問題:從服務器A向客戶端B請求N個文件,進行處理並將其保存到磁盤。

  1. 依序

    • 構建請求的容器,發送單個請求,處理響應,重復直到完成
    • 可以直觀地認為是“標准/初學者”方法
  2. 多線程

    • 再次構建容器,但同時發送多個請求
    • 使用信號量限制活動連接
    • 使用隊列在工作人員和轉儲響應之間共享
    • 讓主線程處理響應
    • 本質上,工作人員是一勞永逸的,並且主要運行在循環中,以檢查隊列中的數據
    • 將關注點與主要處理數據的主要對象分開
  3. 線程池執行器

    • 本質上與解決方案2相似,但是代碼行少得多
    • 推理:“我希望能夠盡快處理回復”
    • 不需要顯式實例化Queue和Semaphore
    • 如果沒記錯的話,在as_completed()使用Queue和Thread結構
    • 這里大致概述
  4. 異步

    • 在這里引起了嚴重的混亂,但是大多數人都理解概念
    • 與解決方案2和3不同,在單個線程上運行
    • 在實現中(非常)接近解決方案3,但寫入磁盤除外
    • 需要使用解決方案3組件才能通過run_in_executor()保存到磁盤

因此,我們已經來到了我目前的困境:為什么我會永遠不想使用asyncio為I / O密集型的工作?

異步編程是一個非常類似於OOP的概念,解決方案3的文檔甚至說“異步執行可以通過線程執行”。 但是,如果我可以在單個線程上實現異步執行(不包括用於阻止對磁盤的I / O的其他線程),為什么還要使用解決方案1-3?

我知道在GIL的情況下,CPython多線程是次優的; 無論如何,我認為沒有理由再有人使用線程或執行程序了。 我做了很多谷歌搜索,看是否能找到一篇很好的文章,說明為什么人們更喜歡使用它們,但是我只發現了一些文章,說明為什么線程(以及隨后使用線程的執行程序)很糟糕:上下文切換( GIL / OS),競爭條件,資源匱乏等...

由於CPython不使用線程來利用多個核心CPU(我相信這是multiprocessing庫),因此線程不用於繁重的計算任務。 因此,將它們限制在I / O限制的操作中以提高性能。 但是,這並沒有給我足夠的理由來理解為什么要在asyncio上使用線程或執行asyncio

如果您可以在單個線程中(可能是2-3個)完成所有操作,為什么還要繼續引入創建,管理和銷毀線程的開銷(無論是顯式的還是通過池/執行器的)?

我認為多線程和異步之間的決定確實取決於您需要哪種多任務。 如果一切都在程序的控制之下,那么異步/多處理可能一直都是正確的選擇。 但是,也許您想開始一項任務,在此前提下,多任務處理是正確的選擇。 例如,您在第三方庫中啟動任務。 使用線程的一個顯而易見的原因是該庫不支持asyncio。 但是,即使它支持異步,您也許也不想信任該庫來隨心所欲地控制您的任務。 然后,您可以使用另一個運行該代碼的asyncio事件循環來啟動新線程。

因此,我認為真正的問題是:何時使用協作以及何時使用搶占式多任務處理。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM