只有在使用python中的asyncio将所有项目放入队列后,才会触发使用asyncio处理队列
我试图用python创建一些代码,将来自生成器的数据(目前是一个简单的计数循环,但在某个点上是传感器数据)放入队列中。一旦进入队列,我想从中提取数据并通过TCP连接发送。这是使用asyncio的好时机,但我做错了什么 当前,脚本将处理所有数字,并且不会返回任何内容。理想情况下,我希望确保队列中有一些内容,这样它就不会清空,每次都会发送一组数据,比如说5个数字。我怎样才能做到这一点只有在使用python中的asyncio将所有项目放入队列后,才会触发使用asyncio处理队列,python,asynchronous,queue,python-asyncio,circular-buffer,Python,Asynchronous,Queue,Python Asyncio,Circular Buffer,我试图用python创建一些代码,将来自生成器的数据(目前是一个简单的计数循环,但在某个点上是传感器数据)放入队列中。一旦进入队列,我想从中提取数据并通过TCP连接发送。这是使用asyncio的好时机,但我做错了什么 当前,脚本将处理所有数字,并且不会返回任何内容。理想情况下,我希望确保队列中有一些内容,这样它就不会清空,每次都会发送一组数据,比如说5个数字。我怎样才能做到这一点 import asyncio import random class responder():
import asyncio
import random
class responder():
def __init__(self, parent=None):
super().__init__()
async def produce(self,queue, n):
for x in range(n):
# produce an item
print('producing {}/{}'.format(x, n))
# simulate i/o operation using sleep
await asyncio.sleep(random.random())
item = str(x)
# put the item in the queue
await queue.put(item)
async def consume(self,queue):
while True:
# wait for an item from the producer
item = await queue.get()
# process the item
print('consuming {}...'.format(item))
# simulate i/o operation using sleep
await asyncio.sleep(random.random())
# Notify the queue that the item has been processed
queue.task_done()
async def run(self,n):
queue = asyncio.Queue()
# schedule the consumer
self.consumer = asyncio.ensure_future(self.consume(queue))
# run the producer and wait for completion
await self.produce(queue, n)
# wait until the consumer has processed all items
await queue.join()
# the consumer is still awaiting for an item, cancel it
self.consumer.cancel()
async def handle_echo(self,reader, writer):
data = await reader.read(100)
message = data.decode()
addr = writer.get_extra_info('peername')
print("Received %r from %r" % (message, addr))
if (message == 'START_RUN'):
data = await self.run(10)
print("Send: %i" % data)
writer.write(data)
await writer.drain()
else:
print("Send: %r" % message)
writer.write(message)
await writer.drain()
print("Close the client socket")
writer.close()
def launch_server(self):
self.loop = asyncio.get_event_loop()
self.coro = asyncio.start_server(self.handle_echo, '127.0.0.1', 7780, loop=self.loop)
self.server = self.loop.run_until_complete(self.coro)
# Serve requests until Ctrl+C is pressed
print('Serving on {}'.format(self.server.sockets[0].getsockname()))
try:
self.loop.run_forever()
except KeyboardInterrupt:
pass
finally:
# Close the server
self.server.close()
self.loop.run_until_complete(self.server.wait_closed())
self.loop.close()
def main():
server = responder()
server.launch_server()
if __name__ == '__main__':
main()
代码生成数字流,但在继续之前,它会在整个列表中运行。此外,我从未得到任何价值回报
我的客户机代码(永远不会得到任何回报)
不确定服务器代码,但
asyncio.create\u task(capture\u stream)
看起来不正确-capture\u stream
是一个协同程序,在将其传递给asyncio.create\u task()
之前需要调用它。另外,由于您正在立即等待任务,因此创建任务没有意义,您可以等待捕获\u stream(reader)
。客户端代码还有许多其他问题reader.at_eof
是一个应该调用的方法。代码通过TCP连接发送非自分隔的START\u RUN
消息,无需任何帧capture\u stream
引用不存在的全局变量who
。tcp\u echo\u客户端
不进行回送。@user4815162342谢谢您的评论,我对asyncio非常陌生。我的印象是,如果我已经有一个循环在运行,我需要在循环中注入活动来完成任务。在我所看到的示例中,他们似乎在协程周围放置了一个任务包装器并等待它。我想至少。我困惑的是我如何排序。我希望队列能够被处理并在队列填满时发送数据,并且仍然有一个可以响应用户输入的GUI。也就是说,要停止数据流,我永远不会有EOF,最终也必须以停止数据流的方式工作。
import asyncio
async def capture_stream(reader):
while not reader.at_eof:
data = await reader.read(100)
print( f'{who} received {len(data)} bytes' )
async def tcp_echo_client(message, loop):
reader, writer = await asyncio.open_connection('127.0.0.1',7780,loop=loop)
print('Send: %r' % message)
writer.write(message.encode())
if (message == "START_RUN"):
data = await reader.read(100)
print('Received: %r' % data.decode())
else:
collect_data = asyncio.create_task(capture_stream)
data = await collect_data
print('Close the socket')
writer.close()
message = 'START_RUN'
loop = asyncio.get_event_loop()
loop.run_until_complete(tcp_echo_client(message, loop))
loop.close()