sync()最多可以花多少时间?

时间:2018-03-30 08:46:36

标签: c linux operating-system system-calls

  

sync()导致对文件系统元数据的所有挂起修改          要写入底层文件系统的缓存文件数据。   sync()总是成功的。

这意味着只有在将所有数据同步到下划线后,sync()才会返回 文件系统。我想知道同步()所有数据需要多长时间? 可能是最差的几分钟或几小时。

我不知道什么参数定义了sync()时间。

我使用sync()

创建了一个测试程序
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

char buffer[536870912];

int main(void)
{
        int fd;
        loff_t nr = 536870912;
        int ret;

        remove("./dummy");
        errno = 0;
        fd = open("./dummy", O_CREAT | O_NOFOLLOW | O_LARGEFILE | O_RDWR, 0700);
        perror("open");

        buffer[10] = 'a';
        buffer[1024] = 'b';
        buffer[10000] = 'c';
        buffer[536870912 - 1000] = 'd';
        buffer[536870912 - 2000] = 'e';
        buffer[536870912 - 1] = 'f';
        int i = 3;
        while (i-- > 0) {
                ret = write(fd, buffer, 536870912);
                if (ret <= 0) {
                        perror("write");
                        return 1;
                }
                nr -= ret;
                printf("sync start\n");
        }
        sync();
        printf("sync done\n");
        return 0;
}

它显示了sync()在多次迭代中所花费的时间不均匀。

有时这个测试程序在sync()时甚至需要30分钟,即sync()不会返回30分钟。这是一种有效的行为吗?

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:3)

永远最大。例如,等待写入断开连接的NFS共享的数据。

答案 1 :(得分:3)

POSIX说:

  

写作虽然已经预定,但未必完成   从sync()返回。

这意味着通常sync()只计划刷新但不等待其完成。所以sync()几乎是异步的,并且它返回的事实并不意味着已经进行了刷新。 sync()调用底层刷新所消耗的时间之间没有关系。你不会知道冲洗是否成功/终止。

答案 2 :(得分:1)

执行sync()可能需要的时间量没有固定的上限。它的任务是将缓冲区缓存中的页面修改为底层文件系统。需要多长时间取决于(以及其他因素):要同步的数据量,以及托管底层文件系统的设备速度有多慢(例如,考虑写入速度非常低的USB记忆棒)。在极端情况下,这可能是几十分钟,甚至几个小时。

接受的答案引用了POSIX的详细信息:

  

写作虽然已经预定,但未必完成   从sync()返回。

但后来将此解释为:

  

这意味着通常sync()只计划刷新   但不要等待它的完成。

我认为这会误解POSIX以及现有实现的性质。在大多数现有(可能是所有现代)实现中,sync()会阻塞,直到所有数据都已同步到存储设备。因此,在sync()返回时,应用程序知道数据已到达底层存储。

但是,POSIX规范还允许另一种实现:内核只是将同步操作调度为异步发生,并立即从sync()调用返回。这显然不如阻塞sync()实现有用,因为执行同步操作的应用程序通常想知道数据何时到达底层设备。在具有&#34;异步&#34;的系统上sync(),应用程序无法确定数据何时登陆存储设备。

POSIX允许任何一种实现方式,大概是因为在API标准化时,一些现有的实现提供了较弱的异步sync()实现,而在这种情况下通常的POSIX方法是标准化为最低共同点。