我如何异步计划文件系统统计操作?

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

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

我可以只包装stat()调用,以便将来与described here类似吗?

解决方法:

os.stat()转换为stat syscall:

$strace python3 -c 'import os; os.stat("/")'
[...]
stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
[...]

这是阻塞的,并且没有办法获得非阻塞的stat syscall.

asyncio通过使用已经存在的非阻塞系统调用来提供非阻塞I / O(请参阅man fcntl,及其O_NONBLOCK标志或ioctl),因此asyncio不会使syscall异步,它以一种不错的方式公开了已经异步的syscall .

仍然可以使用漂亮的ThreadPoolExecutor抽象来使用线程池并行进行阻塞状态调用.

但您可能首先要考虑其他一些参数:

>根据strace -T,stat很快:stat(“ /”,{st_mode = S_IFDIR | 0755,st_size = 4096,…})= 0< 0.000007&gt ;,可能比启动和同步线程快.
> stat可能在很多情况下受IO限制,因此使用更多的CPU将无济于事
>进行并行I / O可能会破坏对随机访问的良好顺序访问,在这种情况下,物理硬盘驱动器可能会变慢.

但是,使用线程池还可以使您的统计数据更快,例如您要访问分布式文件系统.

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

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

上一篇:nginx 记录


下一篇:python-如何从Ansible识别目录是否为NFS挂载?