在 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 中对只读文件设置排他锁的主要内容,如果未能解决你的问题,请参考以下文章