美文网首页
File I/O 同步I/O

File I/O 同步I/O

作者: 无无吴 | 来源:发表于2019-08-12 08:23 被阅读0次

    fsync() and fdatasync()

    #include <unistd.h>
    int fsync(int fd);
    

    对fsync()的调用确保将与文件描述符fd映射的文件相关的所有脏数据写回磁盘。文件描述符FD必须打开以便写入。函数调用将写回数据和元数据,例如创建时间戳和inode中包含的其他属性。在硬盘确认数据和元数据在磁盘上之前,它不会返回。

    以上应该适用于没有写入缓存的硬盘。
    如果是是有写入缓存的硬盘,则应该用fdatasync()

    #include <unistd.h>
    int fdatasync(int fd);
    

    此系统调用与fsync()执行相同的操作,只不过它只刷新将来正确访问文件所需的数据和元数据。并且性能更好。

    int ret;
    ret = fsync(fd);
    if(ret == -1)
      /*error*/
    
    int ret;
    ret = fdatasync(fd);
    if(ret == -1)
      /*error*/
    

    这两个函数都不保证包含该文件的任何更新目录条目都同步到磁盘。这意味着,如果最近更新了文件的链接,文件的数据可能会成功到达磁盘,但关联的目录条目并没有,使文件无法访问。为了确保目录条目的任何更新也提交到磁盘,还必须调用fsync() 针对文件目录打开的文件描述符。
    POSIX要求是实现fsync(),fdatasync()是可选的。
    对于任何常见Linux文件系统上的常规文件,都应该始终实现fsync()系统调用。
    但是,非典型的文件类型(可能是那些没有元数据可同步化的文件类型)或奇怪的文件系统可能只实现fdatasync()。
    所以为了兼容应该这样用:

    if (fsync (fd) == −1) {
    /*
     * We prefer fsync(), but let's try fdatasync()
     * if fsync() fails, just in case.
     */
    if (errno == EINVAL) {
        if (fdatasync (fd) == −1)
          perror ("fdatasync");
        } else
          perror ("fsync");
    }
    

    sync()

    旧式sync()系统调用用于将所有缓冲区同步到磁盘:

    #include <unistd.h>
    void sync(void)
    

    该函数没有参数,也没有返回值。它总是成功的,返回时,所有缓冲区数据和元数据都保证驻留在磁盘上。
    请注意,在繁忙的系统上完成sync()可能需要几分钟或更长时间。

    标志位O_SYNC

    int fd;
    fd = open(file, O_WRONLY | O_SYNC);
    if(fd == -1){
        perror("open);
        return -1;
    }
    

    O_sync标志强制执行这种关系,确保对write()的调用执行同步I/O。
    只有在用尽了所有可能的选择后才能使用同步I/O。

    O_DSYNC and O_RSYNC

    在Linux上,这些标志被定义为O_sync的同义词

    相关文章

      网友评论

          本文标题:File I/O 同步I/O

          本文链接:https://www.haomeiwen.com/subject/eutyjctx.html