我最近在linux中学习文件系统。我了解到,当我们调用fopen()时,库调用将调用malloc()为FILE结构分配空间,并且在此FILE结构中将有一个I / 0的缓冲区。但后来我发现写系统调用实际上是将数据写入内核缓冲区,那么这两个缓冲区之间有什么区别呢?
答案 0 :(得分:6)
您必须了解两件事:fwrite()
是在FILE
结构上运行的标准库例程,但write()
是系统调用。我敢打赌fwrite()
在内部使用write()
。在准备好将数据传递到fwrite()
系统调用之前,没有任何内容使write()
无法提供用户空间IO缓冲。
write()
系统调用直接进入内核并说:“嘿内核,我这里有这个用户空间缓冲区。你会把这个写入存储器吗?”。在这里由内核决定下一步做什么:它将直接进入存储来写入数据,或者,最有可能将数据复制到内核缓冲区,直到它决定是时候修改存储数据。
回到你的问题。任何类型的缓冲都是为了累积数据以推迟转向更昂贵的操作:标准库可能会考虑在每个len
字节上调用系统调用 - 字节昂贵,内核考虑在每个系统调用昂贵的硬盘上等等。
您可能需要阅读此内容,了解缓冲进行的距离https://fgiesen.wordpress.com/2015/10/25/reading-and-writing-are-less-symmetric-than-you-probably-think/
答案 1 :(得分:1)
FILE
结构包含有关打开文件的元数据(模式,流位置等)。它是C标准I / O接口的一部分。
作为FILE
的一部分分配的缓冲区仅获取有限数量的数据(例如,当缓冲流时)。它在fclose()
时被取消分配。您甚至可以使用setvbuf()
提供自己的用户空间标准缓冲区。
只要刷新流或关闭相关文件描述符,内核缓冲区就会收到write()
写的文件内容。
答案 2 :(得分:0)
FILE结构包含有关已打开文件的信息。this defines the FILE struct members。但在内核级别,inode,buffer cache已访问了一个文件。
使用方法copy_to_user和copy_from_user,数据通过缓冲区缓存从用户空间读取/写入磁盘。
答案 3 :(得分:0)
两个缓冲区之间有很大的区别,一个是 kernel
缓冲区,另一个是 user
缓冲区。因此,执行I / O时,基本上发生的是将用户空间中的缓冲区复制到内核空间中的缓冲区中。函数copy_from_user()
完成此任务。
现在出现的问题是,当内核可以访问用户空间时,为什么我们需要两个缓冲区?原因是内核不想直接读取用户缓冲区,因为内核和用户空间都具有不同的地址空间,因此用户空间中的有效地址可能不是内核中的有效地址。
在内核中,如果访问了无效地址,则系统将立即崩溃,因此函数copy_from_user
负责映射用户空间地址和内核空间地址的任务,并检查该地址是否可访问或不。如果没有,那么它只会返回EFAULT
(错误地址)。