Python 可以取消的异步IO键盘输入

Python 可以取消的异步IO键盘输入,python,python-asyncio,Python,Python Asyncio,我正在尝试使用asyncio编写一个同时接受键盘输入的并发Python程序。当我试图关闭程序时,问题出现了。由于键盘输入最终是通过sys.stdin.readline完成的,因此该函数只有在我按下ENTER后才会返回,无论我是stop()事件循环还是cancel()函数的未来 是否有任何方法可以取消使用asyncio的键盘输入 这是我的MWE。它将接受键盘输入1秒,然后stop(): 问题在于,执行者坚持要确保在程序终止时,所有正在运行的期货都已完成。但在这种情况下,您实际上需要一个“不干净”的

我正在尝试使用
asyncio
编写一个同时接受键盘输入的并发Python程序。当我试图关闭程序时,问题出现了。由于键盘输入最终是通过
sys.stdin.readline
完成的,因此该函数只有在我按下
ENTER
后才会返回,无论我是
stop()
事件循环还是
cancel()
函数的
未来

是否有任何方法可以取消使用
asyncio
的键盘输入

这是我的MWE。它将接受键盘输入1秒,然后
stop()


问题在于,执行者坚持要确保在程序终止时,所有正在运行的期货都已完成。但在这种情况下,您实际上需要一个“不干净”的终止,因为没有可移植的方法来取消正在进行的
read()
或异步访问
sys.stdin

取消future没有任何效果,因为一旦其回调开始执行,它就是一个no op。避免不必要的等待的最佳方法是首先避免
在执行器中运行,然后生成自己的线程:

async def ainput():
    loop = asyncio.get_event_loop()
    fut = loop.create_future()
    def _run():
        line = sys.stdin.readline()
        loop.call_soon_threadsafe(fut.set_result, line)
    threading.Thread(target=_run, daemon=True).start()
    return await fut
该线程是手动创建的,并标记为“守护进程”,因此在程序关闭时没有人会等待它。因此,使用
ainput
而不是
run\u in\u executor(sys.stdin.readline)
的代码变体会按预期终止:

async def console_input_loop():
    while True:
        inp = await ainput()
        print(f"[{inp.strip()}]")

# rest of the program unchanged

您必须避免readline,因为它完全按照您所说的做,即等待enter,并且您希望您的键盘输入不等待enter。你还试过什么。@巴尼:没有太多选择。我尝试了
input()
以及
msvcrt.getwch()
。同样的效果。
async def console_input_loop():
    while True:
        inp = await ainput()
        print(f"[{inp.strip()}]")

# rest of the program unchanged