我试图找出不同类型的方法来锁定Linux中的文件,我刚刚遇到了fcntl((。
根据手册页,如果文件上存在冲突的锁,则带有F_SETLKW
的 fcntl(( 应该阻塞。所以我创建了以下代码片段并在两个终端上运行。
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
//lock.c is the file name
void lock() {
struct flock fl;
fl.l_type = F_WRLCK;
fl.l_len = 10;
fl.l_start = 0;
fl.l_whence = SEEK_SET;
fl.l_pid = getpid();
int fd1 = open("lock.c", O_RDWR);
printf("Try to set the lock!n");
int res = fcntl(fd1, F_SETLKW, &fl);
printf("Set the lock with status: %dn", res);
sleep(20);
}
int main(void)
{
lock();
}
我的预期结果是第一个过程应该立即打印出两行,而第二个过程应该只打印出第一行并等待第一个过程完成睡眠,然后打印出第二行。
但事实证明,这两个过程都立即打印出两行并开始休眠。我是否误解了 fcntl(( 的工作原理或代码中是否存在错误?
$./lock
Try to set the lock!
Set the lock with status: 0
好的,我想我发现了问题。我正在使用 WSL 2(昨天更新(和 Windows 10 商店中的 Ubuntu 子系统。而且 fcntl(( 在 WSL 中还不支持/有错误F_SETLK。这是一个相当长的已知问题。
https://github.com/Microsoft/WSL/issues/1927