import queue
qq = queue.Queue()
qq.put('hi')
class MyApp():
def __init__(self, q):
self._queue = q
def _process_item(self, item):
print(f'Processing this item: {item}')
def get_item(self):
try:
item = self._queue.get_nowait()
self._process_item(item)
except queue.Empty:
pass
async def listen_for_orders(self):
'''
Asynchronously check the orders queue for new incoming orders
'''
while True:
self.get_item()
await asyncio.sleep(0)
a = MyApp(qq)
loop = asyncio.get_event_loop()
loop.run_until_complete(a.listen_for_orders())
使用Python 3.6。
我正在尝试编写一个事件处理程序,该事件处理程序将不断侦听queue
中的消息并进行处理(在这种情况下将它们打印出来)。但是它必须是异步-我需要能够在终端(IPython)中运行它,并将其手动输入到queue
(至少在最初用于测试)。
此代码不起作用-它会永远阻止。
我如何使它永久运行,但在while
循环的每次迭代后返回控制权?
谢谢。
旁注:
为了使事件循环与IPython(7.2版)一起使用,我使用了ib_insync
库中的this代码,在上面的示例中,我将该库用于实际问题。 / p>
答案 0 :(得分:2)
这不是异步队列。您需要使用asyncio.Queue
qq = queue.Queue()
异步是一个事件循环。您调用循环传递控件给它,它一直循环直到您的函数完成,这永远不会发生:
loop.run_until_complete(a.listen_for_orders())
您评论了
我有另一个线程,该线程轮询外部网络资源以获取数据(I / O密集型),并将传入的消息转储到该线程中。
异步编写该代码-这样您就可以:
async def run():
while 1:
item = await get_item_from_network()
process_item(item)
loop = asyncio.get_event_loop()
loop.run_until_complete( run() )
如果您不想这样做,您可以做的就是遍历循环,尽管您不想这样做。
import asyncio
def run_once(loop):
loop.call_soon(loop.stop)
loop.run_forever()
loop = asyncio.get_event_loop()
for x in range(100):
print(x)
run_once(loop)
然后,您只需调用异步函数,并且每次调用run_once时,它将检查您的(异步队列),并将控制传递给您的“听订单”函数(如果队列中有项目)。
答案 1 :(得分:2)
您需要将队列设为asyncio.Queue
,并以线程安全的方式将内容添加到队列中。例如:
qq = asyncio.Queue()
class MyApp():
def __init__(self, q):
self._queue = q
def _process_item(self, item):
print(f'Processing this item: {item}')
async def get_item(self):
item = await self._queue.get()
self._process_item(item)
async def listen_for_orders(self):
'''
Asynchronously check the orders queue for new incoming orders
'''
while True:
await self.get_item()
a = MyApp(qq)
loop = asyncio.get_event_loop()
loop.run_until_complete(a.listen_for_orders())
您的其他线程必须将诸如此类的东西放入队列:
loop.call_soon_threadsafe(qq.put_nowait, <item>)
call_soon_threadsafe
将确保正确的锁定,并确保在准备好新的队列项目时唤醒事件循环。