Flock 似乎不起作用

Flock 似乎不起作用

我最近一直在尝试为一个小项目创建一个 shell 脚本,由于某种原因,该flock命令无法正常工作。每当我在子 shell 中以原子方式调用它并将其放入后台时,其他程序似乎都能够读取/写入锁定的文件。

重击会话:

guest@guest ~ $ touch ./temp
guest@guest ~ $ ( flock -x 3 && sleep 99999999999; ) 3>./temp &
[1] 22874
guest@guest ~ $ cat ./temp 
guest@guest ~ $ echo this is a test >./temp 
guest@guest ~ $ cat ./temp 
this is a test
guest@guest ~ $ jobs
[1]+  Running                 ( flock -x 3 && sleep 99999999999 ) 3>./temp &
guest@guest ~ $ bash --version
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

我觉得我可能错过了一些与“flock”程序内部相关的非常简单的东西,但不知道它可能是什么。

答案1

flock执行咨询锁定,这是一种协作锁定方案。这意味着如果您不合作,您将能够覆盖锁定。您可以通过在执行操作之前请求锁定来进行配合,然后在完成操作后释放锁定。这是受锁保护的操作,而不是(必然)锁文件本身。

手册flock(2)在我的系统上:

咨询锁允许协作进程对文件执行一致的操作,但不保证一致性(即,进程仍然可以在不使用咨询锁的情况下访问文件,这可能会导致不一致)。

考虑这个脚本:

#!/bin/sh

( flock -x 9 || exit 1
  echo '1: Locking for 5 secs'; sleep 5; echo '1: Done' ) 9>/tmp/lock &

sleep 1
echo '2: Will now attempt to get lock'

( flock -x 9 || exit 1
  echo '2: Got lock' ) 9>/tmp/lock

# Since the second flock call only performs one operation, the whole last 
# subshell may be replaced by just
#    flock -x /tmp/lock -c echo '2: Got lock'
#
#  (-x and -c are not needed, a lock is exclusive ("write lock")
#   unless -s is used to create a shared lock ("read lock"),
#   and the -c is optional)

输出:

1: Locking for 5 secs
2: Will now attempt to get lock
1: Done
2: Got lock

您可以看到锁是由后台进程获取的,并且其他flock调用必须等待它被释放才能锁定它。

另请注意,此处保护的不是锁定文件,而是echo保证独占的子 shell 中的操作。特别是,锁文件不受写入或读取的不合作进程的保护。

这意味着flock通过在此示例中锁定/tmp/lock,可以保证每个子 shell 的操作(对文件或其他共享数据资源的操作)不会与来自其他子 shell 的冲突操作混合在一起。任何flock使用with/tmp/lock作为锁定文件的其他程序。

为了说明上面的最后一段,请尽可能同时在两个不同的终端中运行上面的脚本(可能会稍微增加睡眠时间),并验证两个竞争脚本是否适当地获取锁(相互等待)。由于在后台进程中请求一个锁,这意味着该锁可能同时运行脚本的两个实例时,无法按脚本中指定的顺序获取。

在您的示例中,交互式 shell 是不配合锁定机制。这就是为什么即使后台子 shell 持有锁,您也能够读取和写入文件。

另请注意,并非所有文件系统都支持使用flock(或其等效的 C 库flock())进行文件锁定。例如,网络文件系统 AFS 和 NFS 在这方面可能存在问题。看https://en.wikipedia.org/wiki/File_locking#Problems

相关内容