如何确保回显到文件中的内容已被刷新?

如何确保回显到文件中的内容已被刷新?

我有两个协作程序 X 和 Y 在同一系统上运行。 X有时使用Y来计算一些信息。我在程序之间使用基于文件的通信。当 X 希望 Y 计算某些内容时,过程如下:

  1. X 将工作描述写入文件 job.txt 并将其放入共享目录中。然后X开始轮询同一目录中是否存在ready.txt文件。
  2. Y 轮询文件 job.txt 是否存在。当文件出现时,Y首先从文件中读取作业信息并将其删除。然后Y执行作业并将结果放入result.txt中。最后Y创建了一个ready.txt文件并再次开始轮询job.txt是否存在。
  3. 当X注意到ready.txt的出现时,它会读取result.txt,删除ready.txt和result.txt,然后继续做其他事情。

问题是 X 有时只收到空的或部分结果文件。 Y 使用 bash 脚本,当前执行如下操作:

rm -f tmp_result.txt
for ((i=first; i <= last; i++)) # Each iteration produces 1 or more result lines
do
  # Compute something...
  echo "One result line with e.g. $values" >> tmp_result.txt
done
cp tmp_result.txt result.txt
touch ready.txt

也就是说,使用 echo 和 I/O 重定向将结果文件的内容一次一行打印到临时文件中。当内容准备好(或应该准备好!)时,它们将被复制到最终的 result.txt 文件中,并通过创建 read.txt 来通知 X。

即使经过相当广泛的实验和谷歌搜索后,我仍然无法找到一种方法来确保 X 始终收到完整的结果。也许 100 次中有 1 到 5 次,X 会将 result.txt 视为完全空(最常见的情况)或仅包含部分结果。

关于脚本逻辑的一些澄清:我最初将结果行直接回显到 result.txt,但这非常不可靠(可能 2 个结果中有 1 个是不完整的)。然后我改为首先将这些行回显到 tmp_result.txt,然后将 tmp_result.txt 移动(重命名)到 result.txt。这导致大约十分之一的结果不完整。如上所示,复制文件效果最佳,但偶尔也会失败。

那么,在 X 开始读取文件之前,如何确保所有回显行都已正确复制到 result.txt 中? Y 只有一些核心 bash 工具可用。

编辑:23 条补充意见

  1. 我已经验证(例如,通过不删除 tmp_result.txt 然后检查它)问题不在于原始结果,而在于它们如何传输到 X。
  2. tmp_result.txt 和 result.txt 都驻留在基于 tmpfs 的 RAM 磁盘上,因此我希望复制/移动文件的速度非常快。
  3. 我在开始使用 tmpfs 后第一次遇到这个问题(最初所有文件都驻留在普通硬盘分区中)。

答案1

看来您可以使用 FIFO 来实现此目的:

mkfifo tasks

制作人:

for i in {1..10}; do echo "task$i"; done > tasks

消费者:

while read task; do echo "received $task"; done  <tasks

这样,您就不必关心同步或删除,也不会在轮询上浪费任何 CPU 时间——如果没有数据或者生产者还没有打开 FIFO,消费者就会阻塞(从而节省 CPU 时间)。如果 FIFO 已满或者消费者还没有打开 FIFO,那么生产者就会阻塞。

答案2

尝试将命令放在 和sync之间。cptouch ready.txt

相关内容