繁体   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