簡體   English   中英

Python 協程是無棧的還是有棧的?

[英]Are Python coroutines stackless or stackful?

關於 Python 協程(我主要是指async/await )是無堆棧還是堆棧,我看到了相互矛盾的觀點。

一些消息來源說他們堆積如山:

雖然其他人似乎暗示他們是無堆棧的,例如https://gamelisp.rs/reference/coroutines.html

GameLisp 的協程遵循 Rust、Python、C# 和 C++ 設置的 model。我們的協程是“無堆棧”的

總的來說,我的理解總是任何有意義的異步/等待實現都意味着無堆棧協程,而堆棧協程基本上是纖程(用戶空間線程,通常或多或少地協同切換),比如 goroutines、Boost.Coroutine,顯然是 Lua 等。

我的理解正確嗎? 或者 Python 協程是否與 C++ 中的協程有某種根本的不同,並且是堆疊的? 還是上述來源的作者有不同的意思?

TLDR:按照C++ 的定義Python 的協程也是無堆棧的。 定義特征是協程的持久化 state 與堆棧分開存儲。

協程是無堆棧的:它們通過返回調用者來暫停執行,恢復執行所需的數據與堆棧分開存儲。 […]

在技術層面上,Python 需要awaitasync for等,以允許子協程掛起它們的父協程。 定期調用 function 是不可能掛起其父級的。

async def foo():
    a = await some_awaitable()  # this may suspend `foo` as well
    b = some_function()         # this cannot suspend `foo`
    return a + b

與無堆棧協程相比,堆棧協程可以從嵌套堆棧框架中暫停。 提升:協程


堆棧和協程

堆棧和協程的交互不像常規例程那樣清晰。 例程正在執行或完成。 這自然映射到 function 執行,將單個執行幀添加到堆棧; 1一旦該幀完成例程完成,幀從堆棧中彈出並丟棄。

相反,協程可以是 executing 、 suspended或 done 。 這就提出了一個問題,即如何在暫停期間處理 state——實際上,如何處理局部變量。 突出的手段有兩種:

  1. 我們可以將每個部分執行視為常規例程。 為了獲得協程語義,當這樣的例程完成時,我們保護它的 state。這允許我們在各個協程之間切換。

  2. 我們可以將整個執行過程視為常規例程。 為了獲得協程語義,當這樣的例程掛起時,我們保護整個堆棧。 這允許我們在各個堆棧之間切換。

解決方案 1. 通常稱為無堆棧——協程獨立於堆棧。 這提供了很多功能,因為每個步驟都是一流的,但它暴露了很多實現細節。 我們必須顯式地模擬嵌套協程執行的堆棧——通常,這就是await的作用。

解決方案 2. 通常稱為stackfull——協程作為堆棧本身的一部分存在。 由於執行在內部發生,因此這消除了很多功能,但隱藏了很多實現細節。 例程與協程的區別是隱藏的,甚至是無關緊要的——任何例程都可以在任何時候暫停。

這些定義不是通用的。 例如,您可能會發現 1. 被稱為 stackfull,因為協程本身保留了自己的暫停堆棧。 如有疑問,請比較語義而不是命名。
然而,這似乎是最普遍的命名方案(請參閱參考資料)。


Python 放在哪里?

從技術角度來看, Python 的協程是無棧的 協程函數創建一流的協程對象,允許部分執行並在掛起期間在內部存儲 state( 作為cr_frame )。 協程是使用顯式await嵌套的,例程不能await任何東西。
值得注意的是,Python 本身不支持堆棧協程:常規例程無法暫停執行。 2個


1幀堆棧的語義並不一定意味着實現具有 function 執行與 memory 堆棧上的幀的 1:1 關系。 相反,將“堆棧”視為運行時的抽象描述,可以通過 function 執行來定義 實現可能會有所不同,但對語言的高級語義沒有可觀察到的差異。 考慮 CPython,它有一個運行 Python 堆棧的 C 堆棧。

2 stackfull協程的缺失不是由語言語義嚴格保證的。 有第三方擴展可以添加 stackfull 協程,即greenlet 恰好,這是由Stackless Python引入的——“Stackless”指的是解釋器對 C-Stack 的使用,而不是協程如何使用堆棧。
然而,這是一個獨立於 Python 自身的awaityield暫停的暫停機制。

參考:

暫無
暫無

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

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