两个进程写入一个文件,防止混合输出

two processes write to one file, prevent mixing the output

我想从两个进程中获取输出并将它们合并到一个文件中,例如:

proc1 >> output &
proc2 >> output &

问题是最终文件中的输出可能会混淆。 例如,如果第一个进程写入:

hellow

第二个进程写入:

bye

结果可能是这样的:

hebylloe

但我希望它们在单独的行中,例如(顺序不重要):

bye

hello

所以我使用flock来同步写入文件,脚本如下:

exec 200>>output
while read line;
  flock -w 2 200
  do echo $line>>output
  flock -u 200
done

和运行过程如下:

proc1 | script &
proc2 | script &

现在的问题是性能明显下降。如果没有同步,每个进程可以以 4MB/秒的速度写入,但使用同步脚本,写入速度为 1MB/秒。

谁能帮我合并两个进程的输出并防止混淆输出?

编辑: 我意识到行长度和 std 缓冲区大小之间存在关系,如果每行的大小小于 std 缓冲区大小,那么一切正常,没有任何混合(至少在我的测试中)。所以我 运行 每个脚本都带有 bufsize 命令:

bufsize -o10KB proc1 | script &
bufsize -o10KB proc2 | script &

现在我想确保这个解决方案是防弹的。我找不到缓冲区大小与现在发生的事情之间的任何关系!!!

Now I want to make sure that this solution is bulletproof. I can not find any relation between buffer size and what happens now!!!

对于完全缓冲的输出流,缓冲区大小决定了使用单个 write(2) call. For a line buffered output stream, a line is written with a single write(2) 调用写入的数据量,只要它不超过缓冲区大小。

If the file was open(2)ed with O_APPEND, the file offset is first set to the end of the file before writing. The adjustment of the file offset and the write operation are performed as an atomic step.

另请参阅这些答案:

  • Atomicity of write(2) to a local filesystem
  • Understanding concurrent file writes from multiple processes