Skip to content Skip to sidebar Skip to footer

Python Asyncio: Reader Callback And Coroutine Communication

I am trying to implement a simple idea of passing a data from stdin to a coroutine: import asyncio import sys event = asyncio.Event() def handle_stdin(): data = sys.stdin.rea

Solution 1:

I think asyncio.Queue is much better suited for this kind of producer/consumer relationship:

import asyncio
import sys

queue = asyncio.Queue()

defhandle_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)asyncdeftick():
    while1:
        data = await queue.get()
        print('Data received: {}'.format(data))

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

if __name__ == '__main__':
    main()

There's less logic involved than with an Event, which you need to make sure you set/unset properly, and there's no need for a sleep, wakeup, check, go back to sleep, loop, like with the global variable. So the the Queue approach is simpler, smaller, and blocks the event loop less than your other possible solutions. The other solutions are technically correct, in that they will function properly (as long as you don't introduce any yield from calls inside if if event.is_set() and if data is not None: blocks). They're just a bit clunky.

Solution 2:

If you want to wait for an event, you should probably be using Event.wait instead of polling is_set.

@asyncio.coroutine
def tick():
    while True:
        yieldfromevent.wait()
        print('Data received: {}'.format(event.data))
        event.clear()

Post a Comment for "Python Asyncio: Reader Callback And Coroutine Communication"