【问题标题】:How much time sync() can take at max?sync() 最多可以花费多少时间?
【发布时间】:2023-04-10 21:11:01
【问题描述】:

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 分钟内不会返回。这是一种有效的行为吗?

任何帮助将不胜感激。

【问题讨论】:

  • 当我将数 GB 的图像写入慢速 (4MB/秒) 拇指驱动器时,同步需要 10 分钟,因为内存中的缓冲区会慢慢耗尽。完成所有写入调用后,将 RAM 大小除以设备速度,这可能会给您一个上限。
  • 如果你修改你的程序运行fsync(fd)而不是sync(),它需要大约相同的时间吗?
  • @MarkPlotnick 它显示了一些改进但不多。
  • 是的,它们应该花费大约相同的时间。如果你想看看时间是否可以改进,你可以在 unix.stackexchange.com 上询问。
  • sync 启动所有同步操作。然后返回 IE实际同步未完成。但是,sync 在之前的同步完成之前不会再次运行。所以正确的方法是调用两次。在命令行上,它看起来像:`sync;同步;

标签: c linux operating-system system-calls


【解决方案1】:

POSIX 说:

写作虽然有计划,但不一定完成 从 sync() 返回。

这意味着通常sync() 只是安排刷新而不等待其完成。所以sync() 几乎是异步的,它返回的事实并不意味着刷新已经完成。 sync() 调用底层刷新所消耗的时间之间没有关系。您也无法知道刷新是否成功/终止。

【讨论】:

  • 对我来说,sync() 有时会在 30 分钟内不返回,是否有效?
  • 是的,这可能是但至少非常非常奇怪。您的文件是在哪种文件系统上创建的?如果它是一个低带宽的网络文件系统(nfs 或类似的),那可能是......
【解决方案2】:

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

【讨论】:

  • 对我来说,sync() 有时会在 30 分钟内不返回,是否有效?
【解决方案3】:

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

接受的答案引用了 POSIX 中的这个细节:

写作虽然有计划,但不一定完成 从 sync() 返回。

然后将其解释为:

这意味着通常sync() 只是安排刷新 但不要等待它完成。

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-24
    相关资源
    最近更新 更多