Linux 中的文件锁定
Linux 中的文件锁定是确保安全处理读/写文件的解决方案。
不,这不是关于用密码保护您的文件。
当多个进程处理同一个文件时,您可能无法获得有意的输出,因为没有定义进程如何处理同一个文件的顺序!
文件锁定是一种解决方案,您可以通过它来确保通过定义顺序来安全地处理要读取/写入的文件。
这听起来可能太复杂了,但这完全没问题。因此,在提出解决方案之前,让我先阐明这个问题。
为什么需要文件锁定
该问题类似于竞争条件,其中多个进程同时修改相同的数据,并且结果严格取决于进程的顺序。
假设有两个进程 A 和 B 正在处理名为 account.txt 的文件(初始数据为 100),它们的行为如下:
A读取当前值并从初始余额中减去20
B 读取当前值并将余额加 50。
从纸面上看,一切看起来都很好,最终数据应该是 130,但最终却是另外一些东西。让我告诉你怎么做:
过程A:读取数据(100)并准备操作。
进程B:读取数据(100)并将当前数据保存到其缓冲区。
过程 A:从 100 减去 20,得到 80。
流程B:不知道原始数据已被修改,并以100作为初始值,因此最终结果是150(100 + 50),而不是您期望的(130)。
文件锁定的实现也随之而来。那么让我们看一下 Linux 中文件锁定的类型。
Linux 中的文件锁定类型
Linux 中有两种类型的文件锁定:
建议锁定
强制锁定
1.咨询锁定
咨询锁定系统不会强制执行力,并且仅在两个进程都参与锁定时才起作用。
例如,进程 A 获取锁并使用文件启动给定任务。
如果进程 B 在没有获取锁的情况下启动,它可以中断进程 A 正在进行的任务。
所以做咨询锁的条件是保证每个进程都参与加锁。
2. 强制锁定
强制加锁可以理解为强制加锁系统,不需要进程的任何配合。
强制锁定会导致内核监视每个打开、读取和写入,以验证该进程不会违反任何进程。
但强制加锁工作需要的步骤相对较多:
使用“-o mand”选项挂载文件。
此外,用户需要关闭组执行位并打开 set-group-ID 以启用强制锁定,因为当您关闭组执行位时,set-group-ID 将不会产生任何影响。
如何启用建议锁定
为此,我将使用集群命令,该命令允许用户处理与建议锁定相关的任务。而flock命令的语法如下:
flock file_to_lock command
首先,让我们创建一个文件来保存默认值:
touch account.txt
现在,让我们将其设置为默认值 100:
echo "100" > account.txt
因此,让我们创建一个简单的脚本来处理流程的逻辑部分:
#!/bin/bash
file="account.txt"
value=$(cat $file)
echo "Read current balance:$value"
#sleep 10 seconds to simulate business calculation
progress=10
while [[ $progress -lt 101 ]]; do
echo -n -e "\033[77DCalculating new balance..$progress%"
sleep 1
progress=$((10+progress))
done
echo ""
value=$((value+$1))
echo "Write new balance ($value) back to $file."
echo $value > "$file"
echo "Done."
现在,让我们创建带有建议锁定的进程 a.sh:
touch a.sh
nano a.sh
并确保它包含以下内容:
#!/bin/bash
flock --verbose balance.dat ./update_balance.sh '-20'
现在,让我们使其可执行:
chmod +x a.sh
让我们来测试一下:
./a.sh
非合作进程的行为
对于此示例,我将创建脚本 b.sh
,该脚本本质上是不合作的。
touch b.sh
nano b.sh
脚本应包含以下内容:
#----------------------------------------
# non-cooperative way
#----------------------------------------
./update_balance.sh '80'
通过执行给定的命令使其可执行:
chmod +x b.sh
让我们来测试一下:
正如你可以清楚地看到的,我想要的值应该是 160,但过程 b 搞砸了,给出了 180。
协作进程的行为
在本节中,我将使进程 b 成为一个协作进程,并进行一些细微的更改,如下所示:
#----------------------------------------
# A cooperative way
#----------------------------------------
flock --verbose balance.dat ./update_balance.sh '80'
好戏开场了:
正如你可以清楚地看到的,进程 B 在第一个进程执行时等待,我得到了想要的结果!
如何在 Linux 中检查锁
您可以使用 lslocks 命令检查所有锁。而且使用方法非常简单。一个命令就是这样:
lslocks
它将显示从命令、锁定类型到路径的所有内容。
最后的话
本指南解释了与 Linux 中的锁相关的所有基础知识,并举例说明了如何使用咨询 Linux 来完成合适的任务。
如果您有任何疑问,请在评论中告诉我。