我想要同步来自协同学之间的数据,最后我得到了一个方法,当它里面有“产生”时,就不会被调用。
更准确地说,当我按照doc ( DatagramProtocol )用datagram_received方法实现一个datagram_received类时,一切都很好,我接收数据。一旦我在方法datagram_received中添加了一个“收益率”,这个方法就再也不会被调用了。下面是一个示例:
loop = asyncio.get_event_loop()
lock = asyncio.Lock(loop=loop)
class MyProtocol(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
global my_data, lock
print("here")
# uncomment the following lines and datagram_received is
# not called at all (never see the "here" on the console)
#yield from lock
#try:
# my_data = float(data.decode())
#finally:
# lock.release()
loop.run_until_complete(loop.create_datagram_endpoint(MyProtocol, sock=create_socket(10000)))
loop.run_forever()根据方法的内容,一个方法怎么会突然不被调用?
我遗漏了什么?应该如何进行同步?
发布于 2017-11-26 03:16:21
我遗漏了什么?
激发您灵感的文档还指出:
可以使用ensure_future()在协议方法中调度Coroutines,但是不能保证执行顺序。协议不知道在协议方法中创建的协同,因此不会等待它们。 若要具有可靠的执行顺序,请在协同线中使用流对象。例如,可以使用StreamWriter.drain() coroutine等待写入缓冲区刷新。
不能在yield from/await中使用datagram_received,您可以:
class MyProtocol(asyncio.DatagramProtocol):
def datagram_received(self, data, addr):
global my_data, lock
print("here")
loop.ensure_future(some_function())
@asyncio.coroutine
def some_function(self):
yield from lock
try:
my_data = float(data.decode())
finally:
lock.release()根据方法的内容,一个方法怎么会突然不被调用?
在函数中使用yield或yield from,使其成为生成器。因此,datagram_received返回生成器对象。要实际执行代码(直到生成),您应该使用next,异步使用(基于生成器的)协同(但是datagram_received不是一个)。
>>> def test():
... print('test')
... yield from 'A'
...
>>> test()
<generator object test at 0x7f4165d42fc0>
>>> next(test())
test
'A'更多关于生成器的信息:https://jeffknupp.com/blog/2013/04/07/improve-your-python-yield-and-generators-explained/
https://stackoverflow.com/questions/47384191
复制相似问题