只有在使用python中的asyncio将所有项目放入队列后,才会触发使用asyncio处理队列

只有在使用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():

我试图用python创建一些代码,将来自生成器的数据(目前是一个简单的计数循环,但在某个点上是传感器数据)放入队列中。一旦进入队列,我想从中提取数据并通过TCP连接发送。这是使用asyncio的好时机,但我做错了什么

当前,脚本将处理所有数字,并且不会返回任何内容。理想情况下,我希望确保队列中有一些内容,这样它就不会清空,每次都会发送一组数据,比如说5个数字。我怎样才能做到这一点

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()