如何使 Linux 上的 `write()` 系统调用立即生效?
How to make `write()` system call on Linux immediately effective?
我正在为 C 编写 REPL(read-execute-print-loop)。我尝试维护一个 header 文件,以便我可以在以前的函数的基础上定义新函数。每当我定义一个新函数时,我都会得到一个新的临时文件,如下所示:
#include "/tmp/header.h"
int foo() {
return func() * func();
}
而 /tmp/header.h
就像:
int func();
int foo();
其中 func()
是先前定义的函数。
所以我需要在 header_fileno
上一次又一次地调用 write()
。我担心的是——在我调用 write(header_fileno, buf, wrsize)
之后,buf
的内容是否可能 存储在某个内核缓冲区 而不是 被写入实际文件?因为如果发生这种情况,我不能指望 header 给出 up-to-date 声明。对于源文件,我也有同样的担忧。如果发生这种情况,有没有办法让它立即生效?
根据 Linux man page,无法保证 write
会将您的数据提交到磁盘。使用fsync
(或关闭文件)将写入的数据刷新到磁盘。 (lseek
也可能有用,如果你只想使用一个文件描述符。)
但是,如果您要经常修改文件的内容,正如您在 REPL 中所期望的那样,您可能希望将它们存储在内存中,这样您就可以更轻松地操作它们。
同样,您可能希望以另一种形式存储其信息,而不是将实时 REPL 代码存储为文本,这样您就可以更轻松地访问和更改它。
您可以安全地假设任何进程,包括当前进程,在您调用 write()
之后调用 read()
将看到更新的文件,即使该文件仍在内核缓冲区,未完全写入磁盘。 POSIX mandates 此行为:
If a read() of file data can be proven (by any means) to occur after a write() of the data, it must reflect that write(), even if the calls are made by different processes.
话虽如此,如果您使用 stdio 函数,这并不适用,它可能会在写入之前缓冲数据。如果您的系统崩溃,它也不保证您的数据不会丢失或损坏;如果您需要该保证,则必须使用 fsync()
或使用 O_SYNC
.
打开文件
我正在为 C 编写 REPL(read-execute-print-loop)。我尝试维护一个 header 文件,以便我可以在以前的函数的基础上定义新函数。每当我定义一个新函数时,我都会得到一个新的临时文件,如下所示:
#include "/tmp/header.h"
int foo() {
return func() * func();
}
而 /tmp/header.h
就像:
int func();
int foo();
其中 func()
是先前定义的函数。
所以我需要在 header_fileno
上一次又一次地调用 write()
。我担心的是——在我调用 write(header_fileno, buf, wrsize)
之后,buf
的内容是否可能 存储在某个内核缓冲区 而不是 被写入实际文件?因为如果发生这种情况,我不能指望 header 给出 up-to-date 声明。对于源文件,我也有同样的担忧。如果发生这种情况,有没有办法让它立即生效?
根据 Linux man page,无法保证 write
会将您的数据提交到磁盘。使用fsync
(或关闭文件)将写入的数据刷新到磁盘。 (lseek
也可能有用,如果你只想使用一个文件描述符。)
但是,如果您要经常修改文件的内容,正如您在 REPL 中所期望的那样,您可能希望将它们存储在内存中,这样您就可以更轻松地操作它们。
同样,您可能希望以另一种形式存储其信息,而不是将实时 REPL 代码存储为文本,这样您就可以更轻松地访问和更改它。
您可以安全地假设任何进程,包括当前进程,在您调用 write()
之后调用 read()
将看到更新的文件,即使该文件仍在内核缓冲区,未完全写入磁盘。 POSIX mandates 此行为:
If a read() of file data can be proven (by any means) to occur after a write() of the data, it must reflect that write(), even if the calls are made by different processes.
话虽如此,如果您使用 stdio 函数,这并不适用,它可能会在写入之前缓冲数据。如果您的系统崩溃,它也不保证您的数据不会丢失或损坏;如果您需要该保证,则必须使用 fsync()
或使用 O_SYNC
.