fsync、fdatasync和sync函数用于让磁盘上实际文件系统与缓冲区高速缓存内容保持同步。函数原型如下:
#include <unistd.h>
int fsync(int filedes);
int fdatasync(int filedes);
void sync(void);
sync函数只是将所有修改过的块缓冲区压入输出队列,然后就返回,它并不等待实际写磁盘操作结束。
fsync函数只对由文件描述符filedes指定的单一文件起作用,并且等待到磁盘操作结束,然后再返回。
fdatasync函数类似于fsync,但它只是影响文件的数据部分。而出数据外,fsync还会同步更新文件的属性。
write、sync、fsycn的作用如下图
实例 x.3.13.1.c
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#define BUFFSIZE 256
int main(void)
{
char filepath[] = "/tmp/myfile"; /*待操作文件路径*/
int f_id1, f_id2; /*文件描述符*/
ssize_t nrdwr; /*实际读写字节书*/
size_t nbytes; /*要写入的字节书*/
off_t offset; /*文件指针偏移量*/
char wbuf[BUFFSIZE] = "0123456789"; /*待写入数据*/
char rbuf[BUFFSIZE]; /*待读入数据*/
/*打开文件,获取文件描述符*/
f_id1 = open(filepath, O_WRONLY | O_CREAT );
if (f_id1 == -1) {
printf("open error for f_id1\n");
return 1;
}
f_id2 = open(filepath, O_RDONLY | O_CREAT | O_RSYNC);
if (f_id2 == -1) {
printf("open error for f_id2\n");
return 1;
}
printf("f_id1:%d\n", f_id1);
printf("f_id2:%d\n", f_id2);
/*把文件指针移动到文件开始处*/
offset = lseek(f_id1, 0, SEEK_SET);
if (offset == -1) {
printf("lseek error for f_id1\n");
return 3;
}
offset = lseek(f_id2, 0, SEEK_SET);
if (offset == -1) {
printf("lseek error for f_id2\n");
return 3;
}
/*通过文件描述符f_id1写入3字节数据[0-2]*/
nbytes = 7;
nrdwr = write(f_id1, wbuf, nbytes);
if (nrdwr == -1) {
printf("write error for f_id1(%d)\n", f_id1);
return 4;
}
fdatasync(f_id1); /*f_id1的数据部分立即写入磁盘*/
fsync(f_id1); /*f_id1的数据部分和属性部分都立即写入磁盘*/
sync(); /*全部块缓冲区都压入输出队列*/
/*通过文件描述符f_id2读入3字节数据[0-2]*/
nbytes = 3;
nrdwr = read(f_id2, rbuf, nbytes);
if (nrdwr == -1) {
printf("write error for f_id2(%d)\n", f_id2);
return 5;
}
nrdwr = nrdwr == 0 ? nbytes : nrdwr;
rbuf[nrdwr] = '\0';
printf("%s\n", rbuf);
close(f_id1);
close(f_id2);
}
编译与执行:
[root@localhost unixc]# rm -f /tmp/myfile
[root@localhost unixc]# cc x.3.13.1.c
[root@localhost unixc]# ./a.out
f_id1:3
f_id2:4
012
[root@localhost unixc]#
分析:此实例只是说明了三个函数的用法,而看不出缓存与同步之间的差异。试图去掉代码中三个函数的调用并不影响运行结果。原因不知道是什么??搞不清楚了。