多个进程可以使用fopen附加到文件而没有任何并发​​问题吗?

时间:2011-09-26 08:26:00

标签: c linux unix fopen

我有一个进程以追加模式打开文件。在这种情况下,它是一个日志文件。示例代码:

int main(int argc, char **argv) {
    FILE *f;
    f = fopen("log.txt", "a");
    fprintf(f, "log entry line");
    fclose(f);
}

两个问题:

  1. 如果我有多个进程附加到同一个文件,每个日志行是否会明显出现,还是可以在进程上下文切换时隔行扫描?
  2. 如果许多进程需要访问该文件,是否会导致并发问题?
  3. 我正在考虑以最简单的方式执行此操作,或者使用zeromq将管道上的日志条目泵送到日志收集器。

    我确实考虑过syslog,但我真的不希望任何平台依赖于该软件。

    这个btw的默认平台是Linux。

6 个答案:

答案 0 :(得分:11)

我不了解fopenfprintf,但你可以使用open O_APPEND文件。然后每个write将在文件的末尾顺利进行(不会与另一个写入混合)。

实际上在查看standard

  

与打开的流关联的文件描述符应为   分配和打开就像通过调用open()一样使用以下内容   国旗:

a or ab          O_WRONLY|O_CREAT|O_APPEND

所以,只要文件已使用fprintf打开,我认为来自多个进程的a是安全的。

答案 1 :(得分:7)

standard(对于open / write,而不是fopen / fwrite)声明

  

如果设置了文件状态标志的O_APPEND标志,则应在每次写入之前将文件偏移设置为文件的末尾,并且在更改文件偏移和写入操作之间不应进行中间文件修改操作。 / p>

要使用fprintf(),您必须对文件禁用缓冲。

答案 2 :(得分:6)

您肯定会拥有平台依赖性,因为Windows无法处理附加到同一文件的多个进程。

关于同步问题,我认为线路缓冲输出/应该/大部分时间保存,即根据我的基于shell的短测试,超过99.99%的短日志线应该是完整的,但不是每次都是如此。明确的语义肯定是可取的,因为无论如何你都无法独立编写这个hack系统,我建议使用syslog方法。

答案 3 :(得分:3)

当你的流程要编写如下内容时:

"Here's process #1"
"Here's process #2"
你可能会得到类似的东西:

"Hehere's process #2re's process #1"

您需要同步它们。

答案 4 :(得分:3)

编辑明确回答您的问题:

  1. 如果我有多个进程附加到同一个文件,每个日志行是否会明显出现,还是可以在进程上下文切换时隔行扫描?
  2. 是的,每个日志行都会完整显示,因为根据msdn/vs2010:

    此函数[即fwrite()]锁定调用线程,因此是线程安全的。对于非锁定版本,请参阅_fwrite_nolock。

    the GNU manpage:

    暗示了同样的含义

    “ - 功能:size_t fwrite(const void * data,size_t size,size_t count,FILE * stream)

    This function writes up to count objects of size size from the array data, to the stream stream. The return value is normally count, if the call succeeds. Any other value indicates some sort of error, such as running out of space. 
    

    - 功能:size_t fwrite_unlocked(const void * data,size_t size,size_t count,FILE * stream)

    The fwrite_unlocked function is equivalent to the fwrite function except that it does not implicitly lock the stream.
    
    This function [i.e., fwrite_unlocked( )] is a GNU extension. "
    
    1. 如果许多进程需要访问该文件,是否会导致并发问题?
    2. 是的,从问题1的含义来看。

答案 5 :(得分:1)

除非您进行某种同步,否则日志行可能会重叠。所以回答第二个问题,这取决于你如何实现锁定和记录代码。如果您只是锁定,写入文件并解锁,如果您有许多进程试图同时访问该文件,则可能会导致问题。