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


34

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


您正在做什么需要并行工作?您不能以允许并行make(1)接管的方式来表达依赖性吗?(即,make -j 9如果您有8个核心,该怎么办)?这具有以更细粒度进行交织工作的附加优势。
vonbrand

Answers:


30

如果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"
}

26

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

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


好人,对此一无所知。但是,这显然是特定于Linux的...
Riccardo Murri 2010年

1
@ Riccardo,FreeBSD有一个类似的命令:lockf(1)
亚历克斯B

lockf(1)但是,它不能以本示例中使用的方式工作。它不能以文件描述符号作为参数。
查理

11

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

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


2
仅供参考-手册页:linux.die.net/man/1/lockfile。:)
卢卡斯·琼斯

请注意(根据联机帮助页),“一旦文件被锁定,则必须每五分钟至少触摸一次该锁定,否则该锁定将被视为过时的,随后的锁定尝试将成功。”
周杰伦

6

mkdir()在POSIX文件系统上,系统调用是原子的。因此,以mkdir某种方式使用命令,使其仅涉及一个调用即可mkdir()实现您的目的。(IOW,请勿使用mkdir -p)。相应的解锁rmdir当然是。

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


rmdir因此也原子?
阿列克谢·马古拉

3

也许lockfile命令可以满足您的需求。

lockfile ~/.config/mylockfile.lock
.....
rm -f important.lock

这似乎删除了错误的文件。
本杰明·W。

1

如果您仅在Unix上运行,请使用fifos。您可以将工作记录写入fifo,并让进程从该文件中读取数据,并且您的阅读器将阻塞fifos。

锁定文件还可以,但是对于您的描述,我会选择fifos


1
您能否详细说明一下fifos如何预防种族状况?
G-Man说'Resstate Monica''Sep

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.