Linux内核chardev读取count值不符:是否因编译器预加载?
问题解答
你的推测不正确,这并非编译器预加载优化导致的,而是用户态运行时/标准库的缓冲机制在起作用:
- 当你在C语言中使用标准库的
fread等文件读取函数时,stdio库默认会启用4096字节的用户态缓冲区。为了减少系统调用的开销(系统调用是相对耗时的操作),它会一次性向内核发起4096字节的read系统调用,把数据缓存到用户态内存中,再分多次返回给应用层的小读取请求(比如你指定的64字节)。此时内核的my_read函数收到的count参数就是标准库实际发起的4096字节。 - Erlang的运行时环境在处理文件读取时,使用了更大的用户态缓冲区(12288字节,即12K)。同样是为了降低系统调用的频次提升性能,当你在Erlang代码中指定读取64字节时,Erlang运行时会主动发起12288字节的
read系统调用,内核的my_read就会收到这个更大的count值,之后Erlang再从自身的用户态缓存中返回你需要的64字节数据。
如果想要验证这一点,可以在C语言中直接调用底层系统调用syscall(SYS_read, fd, buf, 64)(绕过stdio的缓冲机制),此时内核my_read收到的count就会是你指定的64字节;同理,若能找到Erlang中绕过运行时缓冲的原始读取接口,也能得到相同的结果。
内容的提问来源于stack exchange,提问作者Monte Conte
相关产品推荐
相关产品推荐

