传统UNIX实现在内核中设有缓冲区高速缓存或者页面高速缓存,大多数磁盘IO都通过缓冲进行;当将数据写入文件时,内核通常先将该数据复制到其中一个缓冲区中,如果该缓冲区尚未写满,则并不将其排入输出队列,而是等待其写满或者当内核需要重用该缓冲区以便存放其他磁盘块数据时,再将该缓冲排入输出队列,然后待其到达队首时,才进行实际的IO操作,这种输出方式称为延迟写(delayed write)
这是Stevens的一段话,感觉再也搜不到表达得更优美的描述了
延迟写因为要等到缓冲区满了才会进行IO,所以就会减少磁盘读写的次数,但是这样没满就会降低文件内容的更新速度,使得本来想写到文件当中的数据没写到磁盘上
如果想保证磁盘和缓冲区高速缓存一致,系统提供了sync,fsync,fdatasync三个函数,包含在unistd.h里
int fsync(int filedes);
fsync只对由文件描述符filedes指定的单一文件起作用,并且等到写磁盘结束之后才返回,确保将修改过来的块立即写入磁盘;
int fdatasync(int filedes);
fdatasync只会同步更新数据部分;而fsync还会更新文件属性
int sync(void);
sync将所有修改过的块缓冲区排入谢队列,然后就返回,那么并没有到写磁盘结束