cfi*_*cfi 6 python stat python-3.x python-asyncio
将一些代码转换为使用asyncio,我想尽快将控制权交还给asyncio.BaseEventLoop。这意味着避免阻塞等待。
如果没有 asyncio,我会使用os.stat()或pathlib.Path.stat()获取例如文件大小。有没有办法用 asyncio 有效地做到这一点?
我可以结束stat()通话,使其成为类似于此处描述的未来吗?
os.stat()转换为stat系统调用:
$ strace python3 -c 'import os; os.stat("/")'
[...]
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
[...]
Run Code Online (Sandbox Code Playgroud)
这是阻塞的,并且无法获得非阻塞的stat系统调用。
asyncio通过使用已经存在的非阻塞系统调用提供非阻塞 I/O(参见man fcntl,带有它的O_NONBLOCK标志,或ioctl),所以asyncio不是使系统调用异步,它以一种很好的方式公开已经异步的系统调用。
仍然可以使用漂亮的ThreadPoolExecutor抽象来stat使用线程池并行执行阻塞调用。
但是您可以先考虑一些其他参数:
strace -T, statis fast: stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000007>,可能比启动和同步线程快。stat 在很多情况下可能会受到 IO 限制,因此使用更多 CPU 无济于事但是,stat使用线程池也有很多可能让您的s 更快,就像您正在使用分布式文件系统一样。
你也可以看看functools.lru_cache:如果你在stat同一个文件或目录上做多个,并且你确定它没有改变,缓存结果可以避免系统调用。
总而言之,“保持简单”,“os.stat”是获取文件大小的有效方法。