Tinche / aiofiles

File support for asyncio
Apache License 2.0
2.66k stars 150 forks source link

process can't exit normally while there is a ongoing operation #133

Closed ppd0705 closed 2 years ago

ppd0705 commented 2 years ago
from aiofiles import open as aio_open
import asyncio

async def main():
    async with aio_open("/dev/stdin") as f:
        data = await f.readline()
        print(data)

asyncio.run(main())

like above code , I have a task need read stdin data, then do something else. after entering Ctrl-C , the process didn't exit, it need to press Enter key to exit totally.

ppd0705 commented 2 years ago

I found solution from aioconsole, there are 2 ways, just in case someone maybe need, codes show as below

  1. start a new daemon thread:
    
    import sys
    import asyncio
    import threading
    from concurrent.futures import Future

async def run_as_daemon(func, *args): future = Future() future.set_running_or_notify_cancel()

def daemon():
    try:
        result = func(*args)
    except Exception as e:
        future.set_exception(e)
    else:
        future.set_result(result)

threading.Thread(target=daemon, daemon=True).start()
return await asyncio.wrap_future(future)

async def main(): data = await run_as_daemon(sys.stdin.readline) print(data)

if name == "main": asyncio.run(main())

2. use stream reader:
```python
import sys
import asyncio

async def get_steam_reader(pipe) -> asyncio.StreamReader:
    loop = asyncio.get_event_loop()
    reader = asyncio.StreamReader(loop=loop)
    protocol = asyncio.StreamReaderProtocol(reader)
    await loop.connect_read_pipe(lambda: protocol, pipe)
    return reader

async def main():
    reader = await get_steam_reader(sys.stdin)
    data = await reader.readline()
    print(data)

if __name__ == "__main__":
    asyncio.run(main())