【问题标题】:two processes write to one file, prevent mixing the output两个进程写入一个文件,防止混合输出
【发布时间】:2016-12-27 22:46:48
【问题描述】:

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

proc1 >> output &
proc2 >> output &

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

你好

第二个进程写道:

再见

结果可能是这样的:

喜鹊

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

再见

你好

所以我使用了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/秒。

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

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

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

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

【问题讨论】:

  • 如果你只有两个进程,为什么不写两个输出文件,然后合并呢?如果您需要扩大规模,请考虑使用像 log4j 这样的附加程序。
  • 最好(不能解决您的问题)使用echo "$line" >> output(带引号)。
  • 你在写什么?对于普通的日志文件,读取这么多数据的英雄只会在 2 个 proc 写入同一个文件时感到困惑。或者你正在写一些有一天会进入数据库的东西?立即开始。
  • 出于某种原因,我必须用 bash 脚本编写它。我知道我可以轻松处理 C++ 中的情况,但除了 bash 脚本我什么都不能使用...
  • 4 Mb/秒的output 有什么用?

标签: linux bash redirect synchronization flock


【解决方案1】:

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

对于完全缓冲的输出流,缓冲区大小决定了使用单个 write(2) 调用写入的数据量。对于行缓冲输出流,只要不超过缓冲区大小,就会使用单个 write(2) 调用写入一行。

如果文件被打开(2) O_APPEND,文件偏移量首先设置到文件末尾 在写作之前。文件偏移量的调整和写入 操作作为原子步骤执行。

另请参阅以下答案:

【讨论】:

  • 谢谢 Armali 但我如何确定我的 Linux shell 重定向 (>>) 实现是否基于 write(2) 而不是 write(3),因为 write(3) 不能保证这样的事情.!!
  • @ayyoob imani:您是指 POSIX 手册中的write(3) 吗?当然,在 Linux 上,Linux 实现 write(2) 是有效的。
  • 除此之外,POSIX 还说 如果设置了文件状态标志的 O_APPEND 标志,则文件偏移量应在每次写入之前设置为文件末尾,并且没有干预文件修改操作应在更改文件偏移量和写入操作之间发生任何成功的 read() 从文件中被该写入修改的每个字节位置都应返回 write() 指定的数据位置直到再次修改这些字节位置。这些要求将由操作系统内核来满足。
  • 可能会有所帮助——我遇到了使用追加和多进程的 bash 脚本的问题。所以我做了一些测试:这似乎不可靠:( proc1 & proc2 & ) >> outputfile 虽然这看起来可靠:( proc1 & proc2 & ) | cat >> outputfile 推测 stdio 对存在争用问题的文件 i/o 进行了优化。
  • @PaulC - 您手头没有此类问题的可重现示例,对吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-23
  • 1970-01-01
  • 2011-03-13
  • 2015-09-30
相关资源
最近更新 更多