V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
abersheeran
V2EX  ›  程序员

stat() 的调用流程是什么?

  •  
  •   abersheeran ·
    abersheeran · 2021-03-01 12:48:40 +08:00 · 1141 次点击
    这是一个创建于 1152 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在写代码的时候发现一个问题,把 Python 的 os.stat 丢到线程池里跑、直接单线程跑,性能差距相当之大。并且无论是很差劲的机械硬盘、不错的机械硬盘或者 SSD,性能差距比例基本一致。

    于是对 stat 的调用逻辑产生了好奇,谷歌、必应查阅了一番资料之后也没有讲这个事的文章。所以来问问大家。

    des
        1
    des  
       2021-03-01 12:57:41 +08:00 via iPhone
    os 缓存的原因吧?
    liuxu
        2
    liuxu  
       2021-03-01 13:16:29 +08:00
    bleepbloop
        3
    bleepbloop  
       2021-03-01 13:29:53 +08:00
    线程池跑的话也有上下文切换的开销吧,但不知道有多少
    abersheeran
        4
    abersheeran  
    OP
       2021-03-01 14:09:28 +08:00
    @des 我首先对大量不同的文件进行了测试,再对这些文件每个重复调用了十次和百次。如果存在缓存,耗时的增长不应该是实践结果所展示的线性增长。

    我非常好奇调用过程。

    @liuxu 我从未阅读过 Linux 内核代码。虽然这个函数我知道它干了什么,但是那些 flag 不知道什么意思,我对调用过程还是没理解。相比读写文件来说,stat 的磁盘 IO 为什么这么小?
    liuxu
        5
    liuxu  
       2021-03-01 15:28:19 +08:00
    @abersheeran 文件存储在文件系统中,分为属性存储区(inode)和数据存储区(block),stat 只需要读属性存储区

    不需要读过 linux 内核源码,遇到什么查什么而已,把它当做 helloworld 读就行,像我给的这个链接,你不需要搞清楚 flag 是什么意思,只需要知道它们会被填充到 stat 数据结构,并看看调用了哪些方法,根据方法并大概可以知道干了什么,不知道的跟进去看看就知道了

    例如给你发的这个链接,vfs_statx(),根据名字你可以知道 linux 读取文件信息是通过 linux vfs 虚拟文件系统层拿的文件信息
    它内部调用了 user_path_at(),可以知道它读取了文件路径,都不需要往里面看
    然后调用了 vfs_getattr(),是通过 vfs 层读取了文件 attr
    还调用了 real_mount(),那到了当前 mount 数据
    ...

    然后你可能还想知道 user_path_at(),会发现最后调用了 filename_lookup(),然后你再分析它如何那文件信息的,最底层一般是汇编实现,可读性不高,不用太钻,你非要钻也行,无非就是花几天几周几个月而已,你掂量掂量看看值不值就行了


    顺便提一下,c 语言不像现代高级语言,会返回一个对象,搞底层的 c 一般不会这么玩,一般会创建好数据结构,把指针传给个函数,让函数内部操作填充这个数据结构,最后返回 int 型状态信息,所以你会看到 vfs_statx()返回 int,而参数 stat 才是真正返回给调用层的数据结构

    如果你非要知道 flag 的是,拿 flag 查 google 一定可以查出来,但是我给你了,你就往旁边一扔说未阅读过 Linux 内核代码,你对其他人给你带来的帮助给人感觉持有消极态度

    看不懂就别看了,你目前的能力没法满足你的好奇心,过几年再看吧
    abersheeran
        6
    abersheeran  
    OP
       2021-03-01 15:58:18 +08:00
    @liuxu 我不觉得我的态度消极。你发的链接我再三看了,你说的这三个函数,你可能觉得你看函数名就知道干什么的,但是我是压根不知道它们干了啥,我是通过网站的点击跳转功能一层层看的,但是看到最后从 path.dentry 里拿 inode 节点跳一层,赋值给 stat 。我人都傻了,又调回去看。磁盘读写这个发生在哪儿我完全没看到,或者说没看懂。所以我才会说“我对调用过程还是没理解”。你现在回复说了 stat 只需要读属性存储区,我才明白是什么意思。

    总之感谢你的回复。又学到了😀
    0x0208v0
        7
    0x0208v0  
       2021-03-01 16:00:43 +08:00
    @liuxu 大佬,求推荐几本不错的技术书。谢谢大佬
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3131 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 33ms · UTC 10:56 · PVG 18:56 · LAX 03:56 · JFK 06:56
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.