2 种 Linux 文件锁定类型
文件锁定是一种机制,它只允许一个进程在任何特定时间访问文件。通过使用文件锁定机制,许多进程可以以更安全的方式读取/写入单个文件。
在本文中,我们将探索不同类型的 Linux 文件锁定,并使用示例程序了解它们的区别。
我们将通过以下示例来了解为什么需要文件锁定。
- 进程“A”打开并读取包含帐户相关信息的文件。
- 进程“B”也打开文件并读取其中的信息。
- 现在进程“A”更改其副本中记录的帐户余额,并将其写回文件。
- 无法知道自上次读取以来文件已更改的进程“B”具有陈旧的原始值。然后它会更改同一记录的帐户余额,并将其写回文件中。
- 现在该文件将仅包含进程“B”所做的更改。
为避免此类问题,使用锁定来确保“序列化”。
以下是两种类型的 Linux 文件锁定:
- 咨询锁定
- 强制锁定
1. 建议锁定
咨询锁定需要参与进程的合作。假设进程“A”获得了一个 WRITE 锁,并开始写入文件,而进程“B”在不尝试获得锁的情况下打开文件并写入文件。这里进程“B”是非合作进程。如果进程“B”试图获取锁,则意味着该进程正在合作以确保“序列化”。
只有参与进程合作,建议锁定才会起作用。建议锁定有时也称为“非强制”锁定。
2.强制锁定
强制锁定不需要参与进程的合作。强制锁定导致内核检查每次打开、读取和写入,以验证调用进程没有违反给定文件的锁定。有关强制锁定的更多信息,请访问kernal.org
要在 Linux 中启用强制锁定,您需要在文件系统级别以及单个文件上启用它。要遵循的步骤是:
- 使用“-o mand”选项挂载文件系统
- 对于 lock_file,打开 set-group-ID 位并关闭 group-execute 位,以启用对该特定文件的强制锁定。(之所以选择这种方式,是因为当您关闭 group-execute 位时,set-group-ID 对它没有实际意义)
Linux 文件锁定示例
要了解其工作原理,请创建以下 file_lock.c 程序:
#include <stdio.h>
#include <fcntl.h>
int main(int argc, char **argv) {
if (argc > 1) {
int fd = open(argv[1], O_WRONLY);
if(fd == -1) {
printf("Unable to open the file\n");
exit(1);
}
static struct flock lock;
lock.l_type = F_WRLCK;
lock.l_start = 0;
lock.l_whence = SEEK_SET;
lock.l_len = 0;
lock.l_pid = getpid();
int ret = fcntl(fd, F_SETLKW, &lock);
printf("Return value of fcntl:%d\n",ret);
if(ret==0) {
while (1) {
scanf("%c", NULL);
}
}
}
}
使用 gcc 编译程序。
# cc -o file_lock file_lock.c
使用 mount 命令使用“mand”选项重新挂载根文件系统,如下所示。这将启用文件系统级别的强制锁定。
注意:您需要是 root 才能执行以下命令。
# mount -oremount,mand /
在可执行文件(file_lock)所在的目录中创建两个文件,分别命名为“advisory.txt”和“mandatory.txt”。启用 Set-Group-ID 并禁用“mandatory.txt”的 Group-Execute-Bit,如下所示
# touch advisory.txt
# touch mandatory.txt
# chmod g+s,g-x mandatory.txt
测试咨询锁定:现在以“advisory.txt”作为参数执行示例程序。
# ./file_lock Advisory.txt
程序将等待从用户那里获得输入。从另一个终端或控制台,尝试以下操作
# ls >>advisory.txt
在上面的示例中, ls 命令会将其输出写入advisory.txt 文件。即使我们获得了写锁,仍然有一些其他进程(非合作)可以写入文件。这被称为“咨询”锁定。
测试强制锁定: 再次以“mandatory.txt”为参数执行示例程序。
# ./file_lock mandatory.txt
从另一个终端或控制台,尝试以下操作:
# ls >>mandatory.txt
在上面的示例中, ls 命令将等待锁被移除,然后再将其输出写入mandatory.txt 文件。它仍然是一个非合作过程,但锁定是使用强制锁定来实现的。
- 点赞
- 收藏
- 关注作者
评论(0)