gpt4 book ai didi

Python 异步 : reader callback and coroutine communication

转载 作者:太空狗 更新时间:2023-10-29 18:22:05 26 4
gpt4 key购买 nike

我正在尝试实现一个将数据从标准输入传递到协程的简单想法:

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

我的问题是:Event 的方法是否正确?或者有没有更好的方法使用另一个 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.create_task(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.new_event_loop()
loop.add_reader(sys.stdin, handle_stdin)
loop.run_until_complete(tick())

if __name__ == '__main__':
main()

Event 相比,涉及的逻辑更少,您需要确保正确设置/取消设置,并且不需要 sleep、唤醒、检查、回去 sleep ,循环,就像全局变量一样。所以 Queue 方法比其他可能的解决方案更简单、更小,并且阻塞事件循环的次数更少。其他解决方案在技术上正确,因为它们将正常运行(只要您不在 if if event.is_set( )if data is not None: block )。它们只是有点笨重。

关于Python 异步 : reader callback and coroutine communication,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29475007/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com