执行write()
系统调用时会发生什么?
假设我有一个程序使用write()
函数调用将某些数据写入文件。现在C库有自己的内部缓冲区,OS也有自己的缓冲区。
这些缓冲区之间发生了什么交互?
当C库缓冲区被完全填满时,它是否写入OS缓冲区并且当OS缓冲区完全填满时,是否对文件进行了实际写入?
我正在寻找一些详细的答案,有用的链接也会有所帮助。请考虑UNIX系统的这个问题。
答案 0 :(得分:3)
据我所知......
write()
函数是一个较低级别的东西,其中库不缓冲数据(与库{/ 1}}不同,其中库可以/可以缓冲数据。)
尽管如此,唯一的保证是操作系统会在下一个fwrite()
完成之前将数据传输到磁盘驱动器。但是,硬盘驱动器通常有自己的内部缓冲区(有时)超出操作系统的控制范围,因此即使后续的fsync()
已完成,也可能发生电源故障或在实际写入数据之前发生的事情。磁盘驱动器的内部缓冲区到磁盘的物理介质。
基本上,如果你真的必须确保你的数据实际写入磁盘的物理媒体;那么你需要重新设计你的代码以避免这个要求,或接受(小)失败的风险,或确保硬件能够(例如获得UPS)。
答案 1 :(得分:3)
write()系统调用(实际上是所有系统调用)只不过是应用程序和操作系统之间的契约。
现在,一些(异常)文件没有一个write()方法来支持它们。想象一下open()ing“/ dev / null”,并写一个缓冲区给它。系统可以选择不缓冲它,因为它永远不会被写入。
另请注意,write()的行为取决于文件的性质;对于网络套接字,write(fd,buff,size)可以在发送大小字节之前返回(write将返回发送的字符数)。但是,一旦他们被发送,就无法找到它们的位置。它们仍然可以在网络缓冲区中(例如,等待Nagle ......),或网络接口内的缓冲区,或者线路上某处的路由器或交换机中的缓冲区。
答案 2 :(得分:2)
write()
将数据写入操作系统,使其对所有进程可见(如果它可以被其他进程读取)。操作系统如何缓冲它,或者何时将其永久写入磁盘,即库,操作系统,系统配置和特定于文件系统。但是,sync()
可用于强制刷新缓冲区。
保证的是,POSIX要求在符合POSIX的文件系统上,read()
可以证明在write()
返回后发生的{{1}}必须返回写入的数据。
答案 3 :(得分:0)
由于您要求使用UNIX,因此必须记住,文件实际上可能位于已安装的FTP服务器上,例如。例如,文件/dev
和/proc
也不是HDD上的文件。
此外,在Linux上数据不是直接写入硬盘驱动器,而是有一个轮询过程,每隔一段时间刷新所有挂起的写入。
但同样,这些是实施细节,从您的计划的角度来看,这实际上不会影响任何事情。
答案 4 :(得分:0)
依赖于操作系统,请参阅man 2 sync
和(在Linux上)man 8 sync
中的讨论。
答案 5 :(得分:0)
多年前,操作系统应该实施“电梯算法”来安排写入磁盘。我们的想法是尽量减少磁盘写入磁头的移动,这样可以同时为访问磁盘的多个进程提供良好的吞吐量。