3.13 函数sync、fsync和fdatasync
传统的UNIX零碎实现在内核中设有缓冲区高速缓存或页高速缓存,大多数磁盘I/O都通过缓冲区进行。当向文件写入数据时,内核通常先将数据复制到缓冲区,而后排入队列,晚些时候再写入磁盘。这种形式被成为提早写。
通常,当内核须要重用缓冲区来寄存其余磁盘块数据时,它会把所有提早写数据块写入磁盘。为了保障磁盘上理论文件系统与缓冲区中内容的一致性,UNIX零碎提供了sync、fsync和fdatasync三个函数。
#include <unistd.h>int fsync(int fd);int fdatasync(int fd); // 返回值:若胜利,返回0;若出错,返回-1void sync(void);
sync只是将所有批改过的块缓冲区排入写队列,而后就返回,它并不期待理论写磁盘操作完结。
通常,称为update的零碎守护过程周期性地调用(个别每隔30秒)sync函数。这就保障了定期flush内核的块缓冲区。命令sync也调用sync函数。
fsync函数只对有文件描述符fd指定的一个文件起作用,并且期待写磁盘操作完结才返回。fsync可用于数据库这样的应用程序,这种应用程序须要确保批改过的块立刻写到磁盘上。
fdatasync函数相似于fsync,但它只影响文件的数据局部。而除数据外,fsync还会同步更新文件的属性。
3.14 函数fcntl
fcntl函数能够扭转曾经关上文件的属性。
#include <fcntl.h>int fcntl(int fd, int cmd, .../* int arg */); // 返回值:若胜利,则依赖于cmd;若出错,返回-1
在本节的各实例中,第3个参数总是一个整数,与下面所示的函数原型中的正文局部对应。然而在14.3节阐明记录锁时,第3个参数是指向一个构造的指针。
fcntl函数有以下5种性能:
- 复制一个已有的描述符(cmd=F_DUPFD或FDUPFD_CLOEXEC)
- 获取/设置文件描述符标记(cmd=F_GETFD或F_SETFD)
- 获取/设置文件状态标记(cmd=F_GETFL或F_SETFL)
- 获取/设置异步I/O所有权(cmd=F_GETOWN或F_SETOWN)
- 获取/设置记录锁(cmd=F_GETLK、F_SETLK或F_SETLKW)
- F_DUPFD:复制文件描述符fd/新文件描述符作为函数值返回。他是尚未关上的各描述符中大于或等于第3个参数值(取为整型值)中各值的最小值。新描述符与fd共享同一文件表项。然而,新描述符有它本人的一套文件描述符标记,其FD_CLOEXEC文件描述符标记被革除,这示意该描述符在exec时仍放弃无效。
- F_DUPFD_CLOEXEC:复制文件描述符,设置与新描述符关联的FD_CLOEXEC文件描述符标记的值,返回新文件描述符。
- F_GETFD:对应于fd的文件描述符标记作为函数值返回。以后只定义了一个文件描述符编制FD_CLOEXEC。
- F_SETFD:对于fd设置文件描述符标记。新标记按第3个参数(取为整型值)设置。
- F_GETFL:对应于fd的文件状态标记作为函数值返回。
- F_SETFL:将文件状态标记设置为第3个参数的值(取为整型值)。能够更改的几个标记是O_APPEND、O_NONBLOCK、O_SYNC、O_DSYNC、O_RSYNC、O_FSYNC和O_ASYNC。
- F_GETOWN:获取以后接管SIGNO和SIGURG信号的过程ID或过程组ID。
- F_SETOWN:设置接管SIGNO和SIGURG信号的过程ID或过程组ID。正的arg指定一个过程ID,负的arg示意等于arg绝对值的一个过程组ID。
fcntl的返回值与命令无关。如果出错,所有的命令都返回-1,如果胜利则返回某个其余值。下列4个命令有特定的返回值:F_DUPFD、F_GETFD、F_GETFL、和F_GETOWN。第1个命令返回新的文件描述符,第2个和第3个命令返回响应的标记,最初一个命令返回一个整的过程ID或负的过程组ID。