簡體   English   中英

如何使用python生成器創建非阻塞循環協同程序?

[英]How to create non-blocking looping coroutines using python generators?

我正在使用python,我正在嘗試使用生成器作為協同程序。 這意味着我正在使用yield表達式將值傳遞給生成器,然后在各種生成器協同程序之間來回發送消息。

我試圖將協程鏈接到一個迭代一個值的循環,同時保持對源自循環外部的新值的開放。 換句話說,循環應該是非阻塞的:

這是循環:

coroutine_A -> val = (yield) -> does something to val -> coroutine_B.send(other_val)
coroutine_B -> val = (yield) -> does something to val -> coroutine_C.send(other_val)
coroutine_C -> val = (yield) -> does something to val -> coroutine_A.send(other_val)

並且有時我想從這個循環的外部傳遞一個新值到coroutine_A,然后再次關閉它。

EXTERNAL TO LOOP -> coroutine_A.send(message) -> loop continues from new value...

單個部分工作正常,但當我嘗試連接它們時會出現兩個問題。 首先,如何將這些實例化為循環,這似乎是可行的,但會導致更深層次的問題,如下所述。

第一個問題:

在實例化coroutine_A時,coroutine_B尚不存在,因此尚無法告訴coroutine_A它的消息目標是什么。 基本上是雞肉和雞蛋的場景。

我已經嘗試創建一個容器函數來實例化每個協同程序(沒有消息目標),然后創建一個循環來代表協同程序管理消息,如下所示:

def func():
    A = coroutine_A()
    next(A)
    B = coroutine_B()
    next(B)
    C = coroutine_C()
    next(C)
    message_A = A.send(None)
    while True:
        message_B = B.send(message_A)
        message_C = C.send(message_B)
        message_A = A.send(message_C)

這樣做的問題是,它似乎不可能從循環外傳遞消息,因為while循環只是卡在做它的東西。

另一種方法是使用嵌套的yield表達式實例化coroutine_A,以便在實例化時間之后傳入目標:

def coroutine_A():
    while True:
        val = (yield)
        if val is not None:
            coroutine_B_target = val
            while True:
                val = (yield)
                if val is not None:
                    do something to val
                    coroutine_B_target.send(other_val)

A = coroutine_A()
next(A) # prime coroutine
A.send(B) # send in coroutine_B target and step into inner while loop

但是,當coroutine_C嘗試向coroutine_A發送消息時,我得到一個ValueError異常:“生成器已經執行”。

因此,這兩種策略基本上都會導致:

更深層次的問題:

似乎作為協同程序的生成器無法自行循環,似乎這樣做的原因是發送調用是一種“正常方法”,因此有效地嘗試將調用堆棧鏈接回自身,即沒有'允許每個David Beazley的Generators:The Final Frontier第127到131頁的遞歸/重新進入。

因此,有必要將信息傳遞給隊列系統,然后出列並開始新的呼叫。 但是當我嘗試這個時,我似乎陷入了阻止源自循環外部的消息的While循環。

所以,長話短說,一方面,一方面如何保持循環自身,而另一方面,如何保持對來自循環外部的新消息保持開放狀態?

暫無
暫無

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

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