读写两个进程的相同文件是否需要lockfile

时间:2018-08-10 02:06:17

标签: bash multiprocessing locking lockfile

我正在使用Bash脚本并遇到这种情况:

一个bash脚本会将内容写入文件,另一个bash脚本将从同一文件读取内容。

在这种情况下,是否需要锁定文件?我认为我不需要使用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可以写几个关键词,例如successfail等。

2 个答案:

答案 0 :(得分:2)

尽管许多程序员都忽略了这一点,但是由于写入文件不是原子操作,因此可能会遇到问题。当作家这样做

echo success > tmp.log

它可以分为两部分(或更多部分):首先写入suc,然后写入cess\n

如果读者在这些步骤之间执行,则可能只会得到suc而不是整个success行。使用锁定文件可以避免这种竞争情况。

使用shell echo命令进行简短写入不太可能发生这种情况,这就是大多数程序员不必担心的原因。但是,如果编写器是使用缓冲输出的C程序,则可以在任意时间刷新缓冲区,这很可能以部分行结尾。

此外,由于读取器每次都从头开始读取文件,因此您不必担心在上一个中断的地方开始读取。

执行此操作的另一种方法是让编写者使用其他名称写入文件,然后将该文件重命名为读者所要查找的文件。重命名是原子的,因此您可以确保全部或全部不读。

答案 1 :(得分:1)

至少从您的示例来看,read.sh似乎并不真正在意 被写入tmp.log的内容,只有write.sh创建了文件。在这种情况下,read.sh只需检查文件是否存在。

write.sh可以简单地

: > tmp.log

read.sh变为

until [ -e tmp.log ]; do
  sleep 3
done
echo "done"