[英]why asyncio.queue get faild?
Python3, asyncio Task A is putting a number to a queue every 2s, task B is wait for the queue.get() with timeout 1s in a forever loop. Python3,asyncio任务A每2秒将一个数字放入队列,任务B在永久循环中等待超时为1的queue.get()。
I don't know why can't get the number from the queue in task B, if timeout is bigger than 2s, queue.get() is ok. 我不知道为什么不能从任务B的队列中获取数字,如果超时大于2s,queue.get()可以。
import asyncio
class Test:
def __init__(self, loop=None):
self._queue = asyncio.Queue(loop=loop)
self._future = asyncio.Future(loop=loop)
@asyncio.coroutine
def run(self):
asyncio.async(self._feed_queue(2))
asyncio.async(self._recv())
# yield from asyncio.sleep(10.0)
# self._future.set_exception('Fail')
@asyncio.coroutine
def _feed_queue(self, interval):
v = 0
while True:
yield from asyncio.sleep(interval)
print("feed")
yield from self._queue.put(v)
v = v+1
@asyncio.coroutine
def _recv(self):
while True:
try:
print('wait')
# r = yield from asyncio.wait([self._queue.get(), self._future], return_when=asyncio.FIRST_COMPLETED, timeout=1.0)
# for x in r[0]:
# if x.exception():
# raise x.exception()
# print("recv", x.result())
try:
r = yield from asyncio.wait_for(self._queue.get(), timeout=1.0)
print(r)
except:
continue
# print("recv", r)
# in done set
except BaseException as e:
print(e)
break
print("quit")
loop = asyncio.get_event_loop()
t = Test(loop=loop)
asyncio.async(t.run())
loop.run_forever()
output: 输出:
wait
wait
feed
wait
wait
feed
wait
wait
feed
wait
The first call to self._queue.get()
may return the value, but it is not used, and new call is made. 首次调用self._queue.get()
可能会返回该值,但不会使用该值,并且会进行新的调用。
Adjusted to use the call (and to use asyncio.ensure_future
; otherwise, AssertionError("yield from wasn't used with future",)
is raised) 调整为使用调用(并使用asyncio.ensure_future
;否则, asyncio.ensure_future
AssertionError("yield from wasn't used with future",)
)
@asyncio.coroutine
def _recv(self):
future = None
while True:
try:
if future is None:
future = asyncio.ensure_future(self._queue.get())
r = yield from asyncio.wait(
[future, self._future],
return_when=asyncio.FIRST_COMPLETED,
timeout=1.0
)
for x in r[0]:
if x.exception():
raise x.exception()
if x is future:
future = None
print("recv", x.result())
except BaseException as e:
print(e)
break
print("quit")
used asyncio.ensure_future
instead of asyncio.async
because later one is deprecated. 使用asyncio.ensure_future
而不是asyncio.async
因为不推荐使用后者。
It is ok on Python-3.5.1. 在Python 3.5.1上可以。
asyncio.Queue was re-written asyncio.Queue被重写
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.