嘿,有人可以帮我了解同步系统调用的用法吗?

Hey could someone help me understand sync syscall usage?

如标题所说,我不太明白这个系统调用的用法。我正在编写一些将一些数据写入文件的程序,我看到的教程告诉我使用 sys_sync 系统调用。但我的问题是我们为什么以及什么时候应该使用它?数据尚未写入文件?

手册说:

sync - Synchronize cached writes to persistent storage

所以它是写入内存中的文件缓存,而不是磁盘上。

你很少需要使用 sync 除非你正在写入非常重要的数据并且需要确保数据在你继续之前在磁盘上。大量使用 sync 的系统示例之一是数据库(例如 MySQL 或 PostgreSQL)。

所以换句话说,它理论上在你的文件中,而不是在磁盘上,因此如果你断电,你可能会丢失数据,特别是如果你有很多RAM 和许多原始写入,它可能会在很长一段时间内将写入特权缓存,增加数据丢失的风险。


But how can a file be not on the disk? I understand the concept of cache but if I wrote in the disk why would it be in a different place?

首先,当您写入文件时,您将数据发送到内核。您不直接将其发送到磁盘。然后一些内核驱动程序负责将数据写入磁盘。在我使用 Apple 2 和 Amiga 计算机的日子里,我实际上会直接 read/write 到磁盘。至少 Amiga 有一个 DMA,所以你可以设置一个缓冲区,然后告诉磁盘 I/O 进行读取或写入,完成后它会向你发送一个中断。在 Apple 2 上,您必须使用精确计时的汇编语言编写循环以 read/write 软盘上的数据...不同的时代!

虽然您当然可以直接访问磁盘(但是使用像 Linux 这样的内核,您必须确保内核可以让您解放双手...)。

缓存主要用于提高速度。写入磁盘非常慢(就人类而言,它看起来非常快,但与CPU可以推送到驱动器的数据量相比,它仍然很慢)。

所以发生的事情是内核有一个任务要将数据写入磁盘。一旦数据出现在缓存中,该任务就会唤醒,并在所有缓存都传输到磁盘后结束。此任务并行工作。每个驱动器可以有一个这样的任务(这在您有 RAID 1 等系统时特别有用)。

如果您的应用程序填满了缓存,则进一步的写入将被阻止,直到可以替换某些缓存。

and the tutorial I've seen told me to use sys_sync syscall

嗯,这听起来很傻,除非你正在做文件系统写入基准测试或其他事情。

如果你有一个非常重要的文件,你想确保它是“持久的”wrt。在您执行其他操作(例如发送网络数据包以确认传输完成)之前停电,使用 fsync(fd) 仅同步该文件的数据和元数据。

(在 asm 中,从 sys/syscall.h 调用编号 SYS_fsync,文件描述符作为第一个寄存器参数。)

But my problem is why and when should we use this?

通常不要在您编写的程序中使用 sync 系统调用。

在交互式用例中,您通常会使用同名的包装命令 sync(1)。例如使用可移动媒体,让内核现在开始写回,所以一旦你完成输入,卸载将花费更少的时间。或者对于一些基准测试用例。

系统关闭脚本可能 运行 sync 在卸载文件系统(并重新挂载 / 只读)之后,然后 reboot(2) system call.


回复:为什么 sync(2) 存在

不,您的数据在 echo foo > bar.txt 之后还没有在磁盘上。

大多数操作系统,包括 Linux,对文件写入执行回写缓存,而不是直写。

您不希望 write() 系统调用在有可用 RAM 时等待实际磁盘,因为传统的 I/O 方法是同步的,所以简单的单线程程序不会在等待 write() 到 return 期间不能做任何其他事情(比如读取更多数据或计算任何东西)。在每次写入系统调用时阻塞约 10 毫秒将是灾难性的;这与整个调度程序时间片一样长。 (即使使用 SSD 仍然会很糟糕,但当然操作系统是在 SSD 出现之前设计的。)即使只是排队 DMA 也会很慢,特别是对于不是整数对齐扇区的小文件写入,所以即使让磁盘自己的写回写缓存工作也不够好。

因此,文件写入确实会创建尚未发送到磁盘的内核缓冲区的“脏”页面。有时我们甚至可以完全避免 IO,例如对于在任何触发回写之前被删除的 tmp 文件。在 Linux、dirty_writeback_centisecs defaults1500(15 秒)内核开始写回之前,除非可用页面不足 运行ning。 (“低”意味着什么的启发式使用其他可调值)。

如果您真的想立即写入刷新到磁盘并等待数据到磁盘,请使用 -o sync 挂载。或者对于一个程序,让它使用 open(O_SYNC)O_DSYNC(仅针对数据,而不是像时间戳这样的元数据)。


回写还有其他优点,包括即使在文件系统级别也能延迟分配。 FS 可以等到知道文件有多大后再决定将文件放在哪里,从而做出减少碎片的更好决策。例如一个小文件可能会进入一个空白,而这个空白可能不是启动一个可能很大的文件的好地方。 (它只需要保留 space 以确保它可以将它放在 某个地方 。)XFS 是最早进行“惰性”延迟分配的文件系统之一,ext4 也有有一段时间了。