读写两个进程的同一个文件是不是需要lockfile
Posted
技术标签:
【中文标题】读写两个进程的同一个文件是不是需要lockfile【英文标题】:Is lockfile necessary for reading and writing the same file of two processes读写两个进程的同一个文件是否需要lockfile 【发布时间】:2019-01-17 13:31:47 【问题描述】:我正在使用 Bash 脚本并遇到这种情况:
一个 bash 脚本会将内容写入文件,而另一个 bash 脚本将从同一个文件中读取内容。
在这种情况下,是否需要lockfile?我想我不需要使用lockfile,因为只有一个读取过程和一个写入过程,但我不确定。
Bash write.sh:
#!/bin/bash
echo 'success' > tmp.log
Bash read.sh:
#!/bin/bash
while :
do
line=$(head -n 1 ./tmp.log)
if [[ "$line" == "success" ]]; then
echo 'done'
break
else
sleep 3
fi
done
顺便说一句,write.sh
可以写几个关键词,例如success
、fail
等。
【问题讨论】:
如果你只想要文件的第一行,只需使用read line < ./tmp.log
。
【参考方案1】:
虽然许多程序员忽略了这一点,但您可能会遇到问题,因为写入文件不是原子的。当作者这样做时
echo success > tmp.log
它可以分成两个(或更多)部分:首先它写入suc
,然后它写入cess\n
。
如果阅读器在这些步骤之间执行,它可能只得到suc
而不是整个success
行。使用锁定文件可以防止这种竞争条件。
shell echo
命令的短写入不太可能发生这种情况,这就是大多数程序员不担心它的原因。但是,如果编写器是使用缓冲输出的 C 程序,则可以在任意时间刷新缓冲区,这可能会以部分行结束。
此外,由于阅读器每次都是从头开始读取文件,因此您不必担心从前一个中断的位置开始读取。
另一种方法是让写入器写入具有不同名称的文件,然后将文件重命名为读取器正在查找的文件。重命名是原子性的,因此您可以保证阅读全部内容或什么也不阅读。
【讨论】:
如果是这样,我认为lockfile是没有必要的,因为read.sh
只有sleep 3
才会读取suc
。后面的循环可以得到success
。
你还关心文件的内容吗?看起来检查write.sh
是否简单地创建 一个名为./tmp.log
的空文件就足够了。
@chepner 我确实关心文件的内容。如您所见,read.sh
正在寻找关键字“成功”。
但是你展示的write.sh
永远不会写任何东西除了 success
。如果这是真的,那么使用文件的存在而不是内容作为成功的指示会更简单。
@Yves 如果其中一个可能的输出是另一个的扩展,您可能会遇到问题。如果作者可以写successful partially
,那么如果你的读者在作者写完之前读到了,那么你的读者可能会误会。【参考方案2】:
至少从您的示例来看,read.sh
看起来并不真正关心 什么 被写入 tmp.log
,只是 write.sh
创建了该文件。在这种情况下,所有read.sh
需要检查的是文件是否存在。
write.sh
可以很简单
: > tmp.log
而read.sh
变为
until [ -e tmp.log ]; do
sleep 3
done
echo "done"
【讨论】:
嗯,success
只是一个例子,它可能是success
,'fail` 等。这就是为什么我关心我是否应该在读写时锁定文件。
如果它不写success
,你的脚本会退出吗?或者作者会在下一次尝试时覆盖第一行吗?
这听起来像是脚本在完成所有它应该做的事情时写的东西,以表明它是成功还是失败。读者只是定期检查它是否完成以及状态是什么。希望这些检查比它监控的应用程序更频繁。以上是关于读写两个进程的同一个文件是不是需要lockfile的主要内容,如果未能解决你的问题,请参考以下文章
linux 共享内存 可不可以不加锁呢? 系统有两个进程,一个负责写入,一个负责读取
如何在 Linux 中存储 lockfile 命令的 PID