哪些 Unix 命令可以用作信号量/锁?

Lar*_*ang 45 scripting semaphore bash

我想并行运行多个 Bash shell 脚本。但是,我想避免竞争条件。我可以为此目的使用哪些 Unix 命令真正具有原子性,我该如何使用它们?

Ric*_*rri 35

如果lockfile您的系统上没有安装,那么mkdir将完成这项工作:这是一个原子操作,如果目录已经存在,它就会失败(只要您不添加-p命令行开关)。

create_lock_or_wait () {
  path="$1"
  wait_time="${2:-10}"
  while true; do
        if mkdir "${path}.lock.d"; then
           break;
        fi
        sleep $wait_time
  done
}

remove_lock () {
  path="$1"
  rmdir "${path}.lock.d"
}
Run Code Online (Sandbox Code Playgroud)


Ale*_*x B 35

flock(1)

#!/bin/bash

# Makes sure we exit if flock fails.
set -e

(
  # Wait for lock on /var/lock/.myscript.exclusivelock (fd 200) for 10 seconds
  flock -x -w 10 200

  # Do stuff

) 200>/var/lock/.myscript.exclusivelock
Run Code Online (Sandbox Code Playgroud)

这确保了“(”和“)”之间的代码一次仅由一个进程运行,并且该进程确实等待锁定的时间过长。


War*_*ung 12

lockfile(1) 看起来是个不错的选择,但要注意它是procmail软件包的一部分,您可能还没有在您的机器上安装它。它是一个足够流行的软件包,如果尚未安装,应为您的系统打包。我检查过的四个系统中的三个都有,另一个可用。

使用它很简单:

#!/bin/sh
LOCKFILE=$HOME/.myscript/lock
mkdir -p `dirname $LOCKFILE`

echo Waiting for lock $LOCKFILE...
if lockfile -1 -r15 $LOCKFILE
then
    # Do protected stuff here
    echo Doing protected stuff...

    # Then, afterward, clean up so another instance of this script can run
    rm -f $LOCKFILE
else
    echo "Failed to acquire lock!  lockfile(1) returned $?"
    exit 1
fi
Run Code Online (Sandbox Code Playgroud)

我给出的选项使它每秒重试一次,最多 15 秒。如果您希望它永远等待,请删除“-r”标志。

  • 仅供参考 - 手册页:http://linux.die.net/man/1/lockfile。:) (2认同)

小智 7

系统调用mkdir()在 POSIX 文件系统上是原子的。因此,以mkdir只涉及一次调用的方式使用该命令mkdir()将达到您的目的。(IOW,不要使用mkdir -p)。相应的解锁rmdir当然是。

注意事项:mkdir()在网络文件系统上可能不是原子的。

  • 因此 `rmdir` 也是原子的吗? (2认同)