gpt4 book ai didi

linux - 在调用 syncfs() 之前我需要关闭文件吗

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:47:01 24 4
gpt4 key购买 nike

在我的嵌入式系统上,我想确保在关闭文件时数据已安全写入 - 如果系统报告数据已保存,用户应该能够立即切断电源。

我知道执行此操作的正确方法是在目录 (参见 this blog entry )。但是,在我的例子中获取目录的文件描述符有点棘手(我必须通过 /proc/self/fd 找到文件名并从那里派生目录) .对我来说,在整个文件系统上执行 syncfs() 会简单得多 - 我知道这是唯一在文件系统上打开的文件。

现在我的问题是:

  • 执行 syncfs() 就足够了吗?
  • 我是否需要先fclose() FILE *(以便目录条目是最新的)?或者 fflush() 是否足够?
  • 如果需要关闭,在关闭之前dup() 文件描述符是否有用,以便我可以直接将其用于syncfs()

最佳答案

首先,不要混用标准库<stdio.h>调用(如 fprintf(3)fopen(3) )与系统调用(如 open(2)close(2)sync(2) )因为前者是使用进程内缓冲区存储临时数据的库例程,系统为此是不知道的,其他是操作系统接口(interface),让系统负责从现在开始的数据维护。你会很容易区分它们,因为前者使用 FILE *描述符来操作,而最后使用 int要操作的整数描述符。

因此,如果您使用系统调用来确保您的数据正确同步到磁盘,首先绝对有必要 fflush(3) 在执行文件系统之前,进程的缓冲区数据 sync(2)fsync(2)称呼。

没有sync(2)保证发生在 fclose(3)甚至在 close(2)时间,或在 atexit()回调您的进程在 exit() 之前执行的操作.
出于性能原因,操作系统缓冲区写入延迟,并且 close(2)不是使它触发这种事情的事件。试想许多进程可以同时读写同一个文件,并且每个 close(2)触发文件系统刷新可能很难实现。操作系统在 umount(2) 上定期触发此类调用系统调用、系统关闭以及对 sync(2) 的特定调用和 fsync(2)系统调用。

如果您需要维护 FILE *fd描述符打开,只需执行 fflush(fd)对于该描述符,以确保操作系统拥有 fwrite(3) 的所有缓冲区d 或 fprintf(3)先编辑数据。

最后,如果您使用的是 <stdio.h>功能,首先做一个fflush()对于所有 FILE *您已写入的描述符,或调用 fflush(NULL);告诉 stdio 在一次调用中同步所有描述符。然后执行 sync(2)fsync(2)调用以确保您的所有数据都在磁盘上。无需关闭任何东西。

FILE *fd;
...
fflush(fd);
fsync(fileno(fd));
/* here you know that up to the last write(2) or fwrite(3)...
* data is synced to disk */

顺便说一句,你去/dev/fd/<number>的方法获取描述符(您之前拥有的)是错误的,原因有二:

  • 关闭描述符后,/dev/fd/<number>不再是您想要的描述符。通常情况下,它甚至不存在。试试这个:

    #include <string.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <stdio.h>
    #include <errno.h>

    int main()
    {
    int fd;
    char fn[] = "/dev/fd/1";

    close(1); /* close standard output */
    fd = open(fn, O_RDONLY); /* try to reopen from /dev/fd */
    if (fd < 0) {
    fprintf(stderr,
    "%s: %s(errno=%d)\n",
    fn,
    strerror(errno),
    errno);
    exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
    } /* main */
  • 仅通过文件描述符无法获取打开文件所属的目录。在一个多链接文件中,可能有数千个目录指向它。 inode 上(或打开的文件结构中)没有任何内容可让您获取用于打开该文件的路径。使用临时文件的一种常见方法是创建它们并立即 unlink(2)他们,所以没有人可以再次打开它。只要文件保持打开状态,您就可以访问它,但不再有路径指向它。

关于linux - 在调用 syncfs() 之前我需要关闭文件吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42136454/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com