在 Linux 中对只读文件设置排他锁

Posted

技术标签:

【中文标题】在 Linux 中对只读文件设置排他锁【英文标题】:Placing exclusive lock on read-only files in Linux 【发布时间】:2020-06-18 03:50:02 【问题描述】:

假设:

1) 我在 Linux 上有一个文件夹,我只有“读取”和“执行”权限。 2) 具有更高权限(具有“写入”权限)的人会将一些文件放入该文件夹。 3) 并行运行的程序的多个进程会读取文件并对文件进行一些数据处理。

要求:一个文件只能被一个进程读取。完成后,文件将被删除或移动到其他位置。所有文件都不会被写入/编辑。例如,我有 5 个文件和 2 个进程并行运行。我需要确保进程 1 将读取文件 1、3 和 5 并对其执行一些工作。进程 2 将读取文件 2 和 4 并对其执行一些工作。这意味着计算分布是在文件级别完成的。我们不会在文件中分发计算。

在 Linux 上,有两个函数可以放置排他锁:flock 和 fcntl。他们可以互换工作,并尊重其他人放置的锁。问题是这两个功能都需要“写”权限。

Boost 库也有boost::interprocess::file_lock::try_lock() 函数。它与上述两个函数的作用相同。它还需要“写入”权限。

还有其他方法可以对我没有“写”权限的文件设置排他锁吗?

【问题讨论】:

将锁定信息存储在两个进程都可以访问/写入的其他位置,例如共享数据库? @thanhnn 再说一次,你在同步什么?您是否使用锁仅将文件标记为“忙”,例如试图以这种方式分配计算(正如我最初建议的那样)? 如果一个worker想要处理file2,它可以尝试创建/tmp/file2。如果成功,它可以继续。如果没有,它被另一个工人殴打,它可以避免处理该文件。 或者,如果您将 GNU Parallel 称为 sem,它可以充当跨进程的信号量或互斥体。 ***.com/a/37303133/2836621 或者,在该目录中创建一个 FIFO,并让 "文件创建过程" 将文件名写入 FIFO。然后工作人员可以从 FIFO 中读取以获取要处理的文件的名称。 【参考方案1】:

Any access(读或写)足以让 Linux flock 系统调用对文件加锁,这与 fcntl 锁不同,requires 读访问用于读锁,写用于写锁。

您可能正在使用在fcntl 之上模拟flock 的libc。要得到你需要的,直接通过syscall调用系统调用:

#include <sys/syscall.h>
#include <unistd.h>

// from include/uapi/asm-generic/fcntl.h
#define SYS_LOCK_SH 1
#define SYS_LOCK_EX 2
#define SYS_LOCK_UN 8

static int sys_flock(int fd, int op)

    return (int) syscall(SYS_flock, fd, op);

因此,以下程序必须成功:

#include <fcntl.h>
#include <stdio.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <unistd.h>

#define SYS_LOCK_EX 2

static long sys_flock(int fd, int flags)

    return (int) syscall(SYS_flock, fd, flags);


int main(void)

    int fd = open("/etc/hosts", O_RDONLY);
    int ret = sys_flock(fd, SYS_LOCK_EX);

    if (ret) 
        errno = -ret;
        perror("flock");
        return 1;
    

【讨论】:

太棒了!!该解决方案有效。非常感谢。只是补充一点,如果您不希望第二个工人等待,请使用附加标志 LOCK_NB 来阻止它。

以上是关于在 Linux 中对只读文件设置排他锁的主要内容,如果未能解决你的问题,请参考以下文章

linux下修改文件夹权限提示chmod: 更改xx 的权限: 只读文件系统

Linux文件系统只读 解决方案:

让linux下的用户只有只读权限

Linux服务器实现跨用户文件链接并设置只读权限

Linux服务器实现跨用户文件链接并设置只读权限

ESX修复Linux虚拟机重启只读模式