【问题标题】:Why fcntl() is not blocking on F_SETLKW in WSL?为什么 fcntl() 没有阻塞 WSL 中的 F_SETLKW?
【发布时间】:2019-12-09 05:42:12
【问题描述】:

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

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

#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

【问题讨论】:

  • 为我工作。你是如何运行第二个进程的?
  • 也就是说,我从未在现实生活中使用过基于范围的锁。这些天的趋势似乎是守护进程。
  • @o11c 好吧,我在终端中只有第二个标签。在第一个选项卡中,输入 ./lock。看到两行输出后,我转到第二个选项卡,输入 ./lock.
  • 你不应该在那里指定pid吗? fl.l_pid = getpid();
  • @MaximSagaydachny 添加,结果还是一样

标签: c linux ubuntu windows-subsystem-for-linux fcntl


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-11
    • 2011-04-10
    • 2017-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    相关资源
    最近更新 更多