3.12 dup和dup2函数
下面的两个函数用来赋值一个现存的文件描述符
#include<unistd.h> int dup(int filedes); int dup2(int filedes,int filedes2);
成功则返回新的文件描述符,若出错则返回-1;
查看了gun c手册
int dup (int old) [Function]
This function copies descriptor old to the first available descriptor number (the first
number not currently open). It is equivalent to fcntl (old, F_DUPFD, 0).
int dup2 (int old, int new) [Function]
This function copies the descriptor old to descriptor number new.
If old is an invalid descriptor, then dup2 does nothing; it does not close new. Otherwise,
the new duplicate of old replaces any previous meaning of descriptor new, as if
new were closed first.
If old and new are different numbers, and old is a valid descriptor number, then dup2
is equivalent to:
close (new);
fcntl (old, F_DUPFD, new)
However, dup2 does this atomically; there is no instant in the middle of calling dup2
at which new is closed and not yet a duplicate of old.
dup返回的描述符一定是当前可用文件描述符忠最小的数值,用dup2则可以返回filedes2参数指定新描述符的数值。若果filedes2已经打开,则先关闭。如果相同,则不关闭他。
如下图
这些函数返回的新文件描述符与参数filedes共享同一个文件表项。他们都共享同一个文件状态标志(读写等)以及同一当前文件偏移量。
复制一个描述符的另一种方法是使用fcntl函数,调用
dup(filedes)
等效于
fcntl(filedes,F_DUPFD,0);
而调用
dup2(filedes,filedes2);
等效于
close(filedes2);
fcntl(filedes,F_DUPFD,filedes2);
3.13 sync、fsync、和fdatasync函数
传统的UNIX实现在内核忠设有缓冲区高速缓存或页面高速缓存,大多数磁盘I/O都通过缓存进行。当数据文件写入文件中,内核通常先将该数据复制到其中一个缓冲区中,如果改缓冲区尚未写满,则并不将其排入输出队列,二师等待期写满或者内核需要改缓冲区。再将该缓冲区的数据输出。然后待其达到队首时候,才进行实际的I/O操作。这叫延迟写(delayed write)
优点:减少了写的次数。缺点:降低了文件内容更新速度。一旦出现故障,可能一些数据未写进文件。
所以这时候unix提供了三个函数 sync,fsync,fdatesync 三个函数
#inclued<unistd.h> int fsync(int fileds); int fdatesync(int filedes); void sync(void);
下面查阅一下GUN C手册
int sync (void) [Function]
A call to this function will not return as long as there is data which has not been
written to the device. All dirty buffers in the kernel will be written and so an overall
consistent system can be achieved (if no other process in parallel writes data).
int fsync (int fildes) [Function]
The fsync function can be used to make sure all data associated with the open file
fildes is written to the device associated with the descriptor. The function call does
not return unless all actions have finished.
A prototype for fsync can be found in ‘unistd.h’.
This function is a cancellation point in multi-threaded programs. This is a problem
if the thread allocates some resources (like memory, file descriptors, semaphores or
whatever) at the time fsync is called. If the thread gets canceled these resources stay
allocated until the program ends. To avoid this, calls to fsync should be protected
using cancellation handlers.
The return value of the function is zero if no error occurred. Otherwise it is