如何使Linux上的write()系统调用立即生效?

时间:2019-04-28 02:31:01

标签: linux system-calls fwrite

我正在为C编写REPL(读取执行打印循环)。我试图维护头文件,以便可以基于先前的功能定义新功能。每当定义新功能时,都会得到一个新的临时文件,如下所示:

#include "/tmp/header.h"

int foo() {
    return func() * func();
}

/tmp/header.h类似于:

int func();
int foo();

其中func()是先前定义的函数。

因此,我需要一次又一次致电write()上的header_fileno。我担心的是-我叫write(header_fileno, buf, wrsize)之后,buf的内容是否存储在某个内核缓冲区中,而不是被写入实际文件?因为如果发生这种情况,我不能指望标题提供最新的声明。对于源文件,我也有同样的担忧。如果发生这种情况,是否有办法使其立即生效?

2 个答案:

答案 0 :(得分:1)

您可以放心地假设,在调用read()之后进行write()调用的任何进程(包括当前进程)都将看到更新的文件,即使该文件仍在内核中缓冲区并且未完全写入磁盘。 POSIX mandates这种行为:

  

如果可以证明(通过任何方式)在数据的write()之后发生了文件数据的read(),则即使调用是由不同的进程进行的,它也必须反映出write()。 >

话虽如此,如果您使用stdio函数(在写入之前可能会缓冲数据)不适用。它还不能保证在系统崩溃时不会丢失或损坏您的数据;如果需要保证,则必须使用fsync()或使用O_SYNC打开文件。

答案 1 :(得分:0)

根据Linux man page,不能保证write会将您的数据提交到磁盘。使用fsync(或关闭文件)将写入的数据刷新到磁盘。 (如果您只想使用一个文件描述符,lseek也可能很有用。)

但是,如果您打算像在REPL中那样经常修改文件的内容,则可能希望将其存储在内存中,以便更轻松地进行操作。

类似地,您可能希望将其信息以另一种形式存储,而不是将实时REPL代码存储为文本,因此您可以更轻松地访问和更改它。