我正在使用协同例程,通常将它们描述为对管道有用。我发现伯克利(Berkeley)的一个演讲非常有帮助(http://wla.berkeley.edu/~cs61a/fa11/lectures/streams.html#coroutines),但是我遇到了麻烦。在该演讲中,有一个图,其中有一个管道分叉,然后在以后重新组合。如果顺序无关紧要,则重组很容易,使用者有一个产量,但是有两个生产者正在向其发送()。但是,如果订单很重要怎么办?如果我要严格轮换(从左叉获取值,从右叉获取值,起泡,冲洗,重复)怎么办?这可能吗?
私人重组:
def producer1(ncr):
while True:
ncr.send(0)
def producer2(ncr):
while True:
ncr.send(1)
def combine():
while True:
s=(yield)
print(s)
chain = combine()
chain.__next__()
producer1(chain)
producer2(chain)
我得到的输出为0 1 0 1等,但是我很确定这是调度的副作用。有没有办法保证排序,例如yield-from-1,yield-from-2?
要清楚,我知道yield from
和__await__
,但我还不了解它们。
答案 0 :(得分:1)
如果您通过管道“拉”而不是“推”,这并不困难:
for k = 1, 2, ..T:
for t = 0, k, 2k,...T:
for i = 0, 1,...k - 1:
Apply the model to s_t+1 to obtain action a'_t+1
Use the action a'_t+1 to update the next state s_t+i+1
for i = 0, 1,...,k-1:
Use the loss between prediction a'_t+1 and ground truth action a_t+1
to update the recurrent network model using stochastic gradient descent
应该可靠地产生1和0交替出现
您还可以让最终使用者(在这种情况下,与每个值打印一起工作的东西)作为接收者工作,而无需引用 制片人,如果您真的想要:
def producer1():
while True:
yield 0
def producer2():
while True:
yield 1
def combine(*producers):
while True:
for producer in producers:
val = next(producer)
print(s)
combine(producer1(), producer2())
答案 1 :(得分:0)
我想知道了怎么做。无论如何,它都适用于琐碎的管道。这是我的联合收割机:
class combiner():
def __init__(self,n,ncr):
self.q = [ deque() for i in range(n)]
self.n = n
self.x = 0
self.ncr = ncr
@coroutine
def receiver(self,n):
while True:
s=(yield)
self.q[n].append(s)
self.sender()
def sender(self):
while True:
if self.q[self.x]:
self.ncr.send(self.q[self.x].popleft())
self.x = (self.x + 1) % self.n
else:
break
这将在n个流之间循环。基本上,combiner.receiver()是一个协程,它从流中获取数据并将其放入队列。每个流都有一个唯一的队列。 Combiner.sender会清除尽可能多的队列,然后返回。
我有点担心从生成器中调用一个函数然后进行发送可能是 bad ,但是我只是将发送器滚动到接收器中,这个问题就消失了。...< / p>