我如何asyncio安排文件系统统计操作?

时间:2016-06-24 07:55:45

标签: python python-3.x python-asyncio stat

将某些代码转换为使用asyncio,我想尽快将控制权交还给asyncio.BaseEventLoop。这意味着要避免阻止等待。

如果没有asyncio,我会使用os.stat()pathlib.Path.stat()来获取例如文件大小。有没有办法用asyncio有效地做到这一点?

我可以打开stat()来电,这样它的未来类似于described here吗?

1 个答案:

答案 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 -Tstat速度很快:stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000007>,可能比启动和同步线程更快。
  • stat可能在很多情况下是IO绑定的,因此使用更多的CPU无济于事
  • 执行并行I / O可能会破坏对随机访问的良好顺序访问,在这种情况下,物理硬盘可能会变慢。

但是你的stat使用线程池的速度也很快,比如你正在使用分布式文件系统。

您还可以查看functools.lru_cache:如果您在同一个文件或目录上执行多个stat,并且您确定它没有更改,则缓存结果可以避免系统调用

总而言之,“保持简单”,“os.stat” 是获取文件大小的有效方式。

相关问题