将一些代码转换为使用asyncio,我想尽快地控制asyncio.BaseEventLoop
。这意味着要避免阻止等待。asyncio如何安排文件系统统计操作?
没有asyncio我会用os.stat()
或pathlib.Path.stat()
来获得例如。文件大小。有没有一种方法可以有效地用asyncio做到这一点?
我可以直接打包stat()
电话,因此它是类似于described here的未来吗?
将一些代码转换为使用asyncio,我想尽快地控制asyncio.BaseEventLoop
。这意味着要避免阻止等待。asyncio如何安排文件系统统计操作?
没有asyncio我会用os.stat()
或pathlib.Path.stat()
来获得例如。文件大小。有没有一种方法可以有效地用asyncio做到这一点?
我可以直接打包stat()
电话,因此它是类似于described here的未来吗?
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
不使系统调用异步的,它暴露在已经异步系统调用一个不错的方法。
仍然可以使用漂亮的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”是是获取文件大小的有效方式。
你的意思是:你想要一个非阻塞的'os.stat()',这样其他协程可以在其中运行吗? –
@Julien:是的,我认为是的;-)为了让主代码并行运行,我将被迫使用线程而不是asyncio,对吗? – cfi