linux - 无法使用带有文件描述符的群来锁定文件

标签 linux shell concurrency locking

首先让我展示一下什么是有效的。如果我将 flock 与文件路径一起使用,它就可以工作。

1 号航站楼:

[root@centos ~]# flock -x -n /tmp/foo.txt -c "sleep 100"

2 号航站楼:

[root@centos ~]# flock -x -n /tmp/foo.txt -c "sleep 100"
[root@centos ~]# echo $?
1

上面的输出显示我首先在第一个终端中获取了对/tmp/foo.txt 的独占锁。然后在第二个终端中,当我尝试获取同一文件的锁时,它失败了。

现在让我知道什么不起作用。如果我将 flock 与文件描述符一起使用,它就不起作用。

1 号航站楼:

[root@centos ~]# { flock -x -n 100; sleep 100; } 100> /tmp/foo.txt

2 号航站楼:

[root@centos ~]# { flock -x -n 100; sleep 100; } 100> /tmp/foo.txt

上面的输出显示,我首先尝试在第一个终端中获取 /tmp/foo.txt 上的锁。然后在第二个终端中,当我尝试获取同一文件的锁时,它成功了。我预计它会像前面的示例一样失败。为什么会成功?

最佳答案

您正在使用 -n 如果无法立即获取锁,它将终止并且 flock 将失败并退出代码 1。因此,在您执行代码后第一个终端,它会休眠 100 秒。接下来,当你在另一个终端执行相同的操作时,flock 失败并返回 1,但是因为有一个 ; 而你没有对返回码做任何事情,shell 简单地继续执行下一条语句并休眠 100 秒。

因此你需要决定flock的返回码如下。

( flock -x -n 100 || exit 55; sleep 100; ) 100> /tmp/foo.txt

现在,如果您在一个终端中执行上述行,它将休眠 100 秒。接下来,如果您在另一个终端上运行代码,它将立即返回提示符。执行 echo $?,您会看到它已返回 55,因为我们希望使用 || 返回。

|| 所做的是短路。如果 flock 像正常退出一样返回 0,这是 shell 的 true 值,它将不会执行表达式的右侧,并且因此转到下一个语句。如果返回值为 1,这对 shell 来说是一个 false,它将继续计算右边的表达式,即 exit 55 并且因此退出。您也可以通过 if-then-fi 执行此操作。

另请注意,我使用了方括号 () 而不是大括号 {}。这是因为,如果您使用大括号,那么命令将在当前 shell 中执行,如果您使用 exit,那么它将从当前 shell 退出。括号将创建一个子 shell,因此从那里执行 exit 会终止子 shell 并返回到原始 shell。

它适用于您使用 -c 的第一个示例,因为您在 flock 参数中包含了单个命令。因此,如果 flock 无法获取锁,它就不会执行语句并终止。

关于linux - 无法使用带有文件描述符的群来锁定文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30658145/

相关文章:

c# - MonoDevelop 无法识别 MonoBehaviour

linux - 示例 Bash 脚本或命令以检索目录中的数字文件

python - 调用 python multiprocessing .join() 方法是否有成本

Java:证明DCL不起作用

linux - Bash:如何避免行首出现空白?

python - 在启动时启动 couchpotato.py,无需保持 ssh session 打开。 ReadyNAS (Debian 7)

linux - 捕获一张 Excel 工作表

linux - 使用 AWK 或 SED 以及以下标签以逗号分隔

java - http请求的线程池

c - getc 是宏还是函数?