Zau*_*bov 10 python coroutine python-3.x python-3.4 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()
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常,但是带有变量而不是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
Run Code Online (Sandbox Code Playgroud)
我的问题是:方法Event是否正确?或者有更好的方法与另一个asyncio对象来处理这种问题?那么,如果方法Event很好,使用变量也可以吗?
谢谢.
dan*_*ano 15
我认为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()
Run Code Online (Sandbox Code Playgroud)
涉及的逻辑少于a Event,你需要确保正确设置/取消设置,并且不需要sleep唤醒,检查,返回睡眠,循环,就像使用全局变量一样.因此,该Queue方法更简单,更小,并且阻止事件循环比其他可能的解决方案更少.其他解决方案在技术上是正确的,因为它们将正常运行(只要你不在yield fromif if event.is_set()和if data is not None:block中引入任何调用).他们只是有点笨重.
| 归档时间: |
|
| 查看次数: |
5715 次 |
| 最近记录: |