首页 > 解决方案 > 为什么 fcntl() 没有阻塞 WSL 中的 F_SETLKW?

问题描述

我试图找出在 linux 中锁定文件的不同类型的方法,但我刚刚遇到了 fcntl()。

根据手册页, fcntl()F_SETLKW如果在文件上持有冲突锁,则应该阻止。所以我创建了以下代码片段并在两个终端上运行。

#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: %d\n", res);

    sleep(20);
}

int main(void)
{
    lock();
}

我的预期结果是第一个进程应该立即打印出两行,而第二个进程应该只打印出第一行并等待第一个进程完成睡眠然后打印出第二行。

但事实证明,这两个进程都会立即打印出这两行并开始休眠。我误解了 fcntl() 的工作原理还是代码中存在错误?

$./lock
Try to set the lock!
Set the lock with status: 0

标签: clinuxubuntuwindows-subsystem-for-linuxfcntl

解决方案


好的,我想我找到了问题所在。我正在使用来自 Windows 10 商店的 WSL 2(昨天更新)和 Ubuntu 子系统。而且 fcntl() 还不支持/在 WSL 中存在错误 F_SETLK。这是一个相当长一段时间内的已知问题。

https://github.com/Microsoft/WSL/issues/1927


推荐阅读