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

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

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

两个问题:

  1. 如果我有多个进程附加到同一个文件,每个日志行会显示不同,或者它们可以在进程上下文切换时交错?
  2. 如果大量进程需要访问文件,会写入块吗,从而导致并发问题?

我正在考虑以最简单的forms进行此操作,或者使用zeromq将日志条目通过pipe道泵到日志收集器。

我确实考虑过系统日志,但是我并不想要软件上的任何平台依赖。

默认的平台是Linux的这个顺便说一句。

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

关于同步问题,我认为线路缓冲输出/应该/大部分时间都可以节省,即根据我短小的基于shell的测试,超过99.99%的短日志行应该是完整的,但不是每一次。 显式语义是绝对可取的,因为无论如何你都不能写这个黑客系统,所以我推荐一个系统日志方法。

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

其实看标准 :

与打开的流相关联的文件描述符应该被分配和打开,就好像通过调用open()以下面的标志一样:

 a or ab O_WRONLY|O_CREAT|O_APPEND 

所以我想只要用a打开文件就可以从多个进程中fprintf安全。

标准 (打开/写入,而不是fopen / fwrite)指出

如果设置了文件状态标志的O_APPEND标志,则在每次写入之前,文件偏移量应设置为文件末尾,在改变文件偏移量和写入操作之间不得进行中间文件修改操作。

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

当你的流程将会写下如下的东西:

 "Here's process #1" "Here's process #2" 

你可能会得到像这样的东西:

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

你将需要同步它们。

编辑明确回答你的问题:

  1. 如果我有多个进程附加到同一个文件,每个日志行会显示不同,或者它们可以在进程上下文切换时交错?

是的,每个日志行将显示完整,因为根据msdn / vs2010:

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

GNU手册页也是这样说的:

“ – 函数: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 [ie, fwrite_unlocked( )] is a GNU extension. " 
  1. 如果大量进程需要访问文件,会写入块吗,从而导致并发问题?

是的,来自问题1的暗示。

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