3

我编写了一个并行执行命令的脚本。我让他们都向同一个日志文件写入一个条目。顺序错误或条目是否交错都没有关系,但我注意到有些条目丢失了。我可能应该在写入之前锁定文件,但是,如果多个进程同时尝试写入文件,是否会导致条目丢失?

4

2 回答 2

7

是的,如果不同的进程独立打开并写入同一个文件,可能会导致重叠写入和丢失数据。发生这种情况是因为每个进程都会获得自己的文件指针,该指针仅通过本地写入前进。

除了锁定,更好的选择可能是在所有工作进程的祖先中打开日志文件一次,让它继承fork(),并由它们用于日志记录。这意味着将有一个共享文件指针,当任何进程写入新条目时该指针会前进。

于 2013-03-13T12:35:00.070 回答
2

在脚本中,您应该使用“>> file”(双倍大于)将输出附加到该文件。解释器将以“附加”模式打开目的地。如果您的程序还想追加,请遵循以下指令:

以“追加”模式(“a+”)打开一个文本文件,并优先打印整行(不要执行多个 'print' 后跟一个最终的 'println',而是使用单个 'println' 打印整行)。

fopen 文档说明了这一点:

DESCRIPTION
     The fopen() function opens the file whose  pathname  is  the
     string  pointed to by filename, and associates a stream with
     it.

     The argument mode points to a string beginning with  one  of
     the following sequences:

     r or rb             Open file for reading.


     w or wb             Truncate to  zero  length or create file
                         for writing.


     a or ab             Append; open or create file for  writing
                         at end-of-file.


     r+ or rb+ or r+b    Open file for update (reading and  writ-
                         ing).


     w+ or wb+ or w+b    Truncate to zero length or  create  file
                         for update.


     a+ or ab+ or a+b    Append; open or create file for  update,
                         writing at end-of-file.

字符 b 没有影响,但允许符合 ISO C 标准(请参阅标准 (5))。如果文件不存在或无法读取,则以读取模式(r 作为模式参数中的第一个字符)打开文件将失败。

使用附加模式(a 作为模式参数中的第一个字符)打开文件会导致对文件的所有后续写入被强制到当时的当前文件结尾,而不管对 fseek(3C) 的干预调用如何。如果两个单独的进程打开同一个文件进行追加,每个进程都可以自由地写入文件,而不必担心破坏另一个正在写入的输出。 两个进程的输出将按照写入的顺序混合在文件中。

正是由于这种混合,您希望优先使用仅使用 'println'(或其等效项)。

于 2013-03-14T18:41:02.500 回答