Python `select.select` 与 `asyncio.wait`。该用哪个?

问题描述 投票:0回答:1

这两个函数都可用于等待一组文件中的第一个文件变得可读。

select
使用 UNIX 系统调用;
asyncio.wait
使用绿色线程。每种方法理论上的优缺点是什么?它们是否使用相同的底层原语(特别是,
asyncio.wait
是否以某种方式发现它正在等待文件描述符并调用
select
)?

import select
devices = ["/dev/input/event6", "/dev/input/event3"]
files = [open(device) for device in devices]
first_fileno = select.select([file.fileno() for file in files], [], [])[0][0]
print([file.name for file in files if file.fileno() == first_fileno][0])
import aiofiles
import asyncio
import contextlib

async def read_and_return(file):
    contents = await file.read(1)
    return file, contents

async def main(devices):
    async with contextlib.AsyncExitStack() as stack:
        files = [await stack.enter_async_context(aiofiles.open(device, "rb")) for device in devices]
        tasks = [asyncio.create_task(read_and_return(file)) for file in files]
        completed, incompleted = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED)
        file, contents = list(completed)[0].result()
        print(file.name)

devices = ["/dev/input/event6", "/dev/input/event3"]
asyncio.run(main(devices))
python asynchronous concurrency python-asyncio
1个回答
0
投票

Asyncio 旨在抽象出“select”等机制的使用以及回调的需要。使用 asyncio 的好处是能够编写协作并发代码,它只会在您编写代码时运行您的代码,不会发生突然的状态更改,并且只提供了在显式位置并行或在后台运行的机会。

select
调用是一种机制,旨在显式检查某些内容的准备情况,然后处理它 - 比 asyncio 更“低级”。

因此,我们的想法是,我们将使用更高的抽象:asyncio 机制来编写单线程并发代码,而另一种方式将重写 asyncio 已经设计的代码,并设计为以有效的方式容纳,不仅基于“选择”的 I/O,还有一系列其他并发编程机制。

例外应该是,如果您需要

select.select
调用,并且程序的其余部分不需要单线程并发,并且使用 asyncio 会使事情变得更加复杂(例如必须搜索特定的 async当您已经有可用的同步代码时,请使用库)。

经验法则应该是使用异步机制 - 要么是原生 asyncio,要么是像“trio”这样的替代实现 - https://trio.readthedocs.io/en/stable/

© www.soinside.com 2019 - 2024. All rights reserved.