ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python asyncio:读者回调和协同通信

2019-10-06 18:59:44  阅读:313  来源: 互联网

标签:python-3-4 python python-3-x coroutine python-asyncio


我试图实现一个简单的想法,将数据从stdin传递到协程:

import asyncio
import sys

event = asyncio.Event()

def handle_stdin():
    data = sys.stdin.readline()
    event.data = data  # NOTE: data assigned to the event object
    event.set()

@asyncio.coroutine
def tick():
    while 1:
        print('Tick')
        yield from asyncio.sleep(1)

        if event.is_set():
            data = event.data  # NOTE: data read from the event object
            print('Data received: {}'.format(data))
            event.clear()

def main(): 
    loop = asyncio.get_event_loop()
    loop.add_reader(sys.stdin, handle_stdin)
    loop.run_until_complete(tick())    

if __name__ == '__main__':
    main()

这段代码工作正常,但是带有变量而不是Event对象的简化版本也适用:

data = None

def handle_stdin():
    global data
    data = sys.stdin.readline()

@asyncio.coroutine
def tick():
    while 1:
        print('Tick')
        yield from asyncio.sleep(1)

        global data
        if data is not None:
            print('Data received: {}'.format(data))
            data = None

我的问题是:事件的方法是正确的吗?或者有更好的方法与另一个asyncio对象来处理这种问题?
那么,如果使用Event的方法很好,使用变量也可以吗?

谢谢.

解决方法:

我认为asyncio.Queue更适合这种生产者/消费者关系:

import asyncio
import sys

queue = asyncio.Queue()

def handle_stdin():
    data = sys.stdin.readline()
    # Queue.put is a coroutine, so you can't call it directly.
    asyncio.async(queue.put(data)) 
    # Alternatively, Queue.put_nowait() is not a coroutine, so it can be called directly.
    # queue.put_nowait(data)

async def tick():
    while 1:
        data = await queue.get()
        print('Data received: {}'.format(data))

def main(): 
    loop = asyncio.get_event_loop()
    loop.add_reader(sys.stdin, handle_stdin)
    loop.run_until_complete(tick())    

if __name__ == '__main__':
    main()

与事件相比,涉及的逻辑更少,您需要确保正确设置/取消设置,并且不需要睡眠,唤醒,检查,返回睡眠,循环,就像使用全局变量一样.因此,Queue方法更简单,更小,并且阻止事件循环比其他可能的解决方案更少.其他解决方案在技术上是正确的,因为它们将正常运行(只要你没有从内部调用引入任何收益,如果event.is_set()和数据不是None:blocks).他们只是有点笨重.

标签:python-3-4,python,python-3-x,coroutine,python-asyncio
来源: https://codeday.me/bug/20191006/1861715.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有