c - 为什么 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
解决方案
好的,我想我找到了问题所在。我正在使用来自 Windows 10 商店的 WSL 2(昨天更新)和 Ubuntu 子系统。而且 fcntl() 还不支持/在 WSL 中存在错误 F_SETLK。这是一个相当长一段时间内的已知问题。
推荐阅读
- c# - 在 Windows IoT 上将 Sqlite 与 asp.net 核心应用程序一起使用
- ormlite-servicestack - 分析时,Servicestack.Ormlite 中的选择命令在 4.0.54 和 4.0.56 中有所不同
- angular - 无法安装和配置本地cli到较低版本来构建项目
- php - codeigniter htaccess php指令不起作用
- python - 在heroku上安排一个python脚本
- reactjs - React + redux 容器
- elasticsearch - 如何直接从弹性搜索中获取按字段过滤的选项?
- rdf - 从数据挖掘到 RDF
- oracle - 如何在 Oracle Report 公式列的绑定变量中传递多个字符串?
- elasticsearch - JVM 缓冲池只会增长