将某些代码转换为使用asyncio,我想尽快将控制权交还给asyncio.BaseEventLoop
。这意味着要避免阻止等待。
如果没有asyncio,我会使用os.stat()
或pathlib.Path.stat()
来获取例如文件大小。有没有办法用asyncio有效地做到这一点?
我可以打开stat()
来电,这样它的未来类似于described here吗?
答案 0 :(得分:3)
os.stat()
转换为stat
系统调用:
$ strace python3 -c 'import os; os.stat("/")'
[...]
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
[...]
阻塞了,并且无法获得非阻塞stat
系统调用。
asyncio
通过使用已经存在的非阻塞系统调用来提供非阻塞I / O(请参阅man fcntl
,其O_NONBLOCK
标记或ioctl
) ,所以asyncio
没有使syscalls异步,它以一种很好的方式暴露了已经异步的系统调用。
仍然可以使用漂亮的ThreadPoolExecutor抽象来使用线程池并行地进行阻塞stat
调用。
但您可以先考虑其他一些参数:
strace -T
,stat
速度很快:stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000007>
,可能比启动和同步线程更快。stat
可能在很多情况下是IO绑定的,因此使用更多的CPU无济于事但是你的stat
使用线程池的速度也很快,比如你正在使用分布式文件系统。
您还可以查看functools.lru_cache
:如果您在同一个文件或目录上执行多个stat
,并且您确定它没有更改,则缓存结果可以避免系统调用
总而言之,“保持简单”,“os.stat” 是获取文件大小的有效方式。