web-dev-qa-db-ja.com

セマフォ/ロックとして使用できるUnixコマンドは何ですか?

複数のBash Shellスクリプトを並行して実行したい。ただし、競合状態は避けたい。この目的で使用できるUnixコマンドはtruly atomicであり、どのように使用できますか?

39
Larry Wang

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"
}
35
Riccardo Murri

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

これにより、 "("と ")"の間のコードが一度に1つのプロセスによってのみ実行され、プロセスがロックを長く待ちすぎることが保証されます。

30
Alex B

lockfile(1)は良い候補のようですが、これは procmail パッケージの一部であり、まだマシンにインストールされていない可能性があることに注意してください。それはまだインストールされていない場合にシステムにパッケージ化するのに十分人気のあるパッケージです。私がチェックした4つのシステムのうち3つにはそれがあり、もう1つには利用可能です。

使い方は簡単です:

#!/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

私が指定したオプションでは、1秒に1回、最大15秒間再試行します。永久に待機させたい場合は、「-r」フラグをドロップします。

12
Warren Young

システムコールmkdir()は、POSIXファイルシステムではアトミックです。したがって、mkdirコマンドをmkdir()の呼び出しを1つだけ含むような方法で使用すると、目的が達成されます。 (IOW、_mkdir -p_は使用しないでください)。もちろん、対応するロック解除はrmdirです。

警告エンプター:mkdir()は、ネットワークファイルシステムではアトミックでない可能性があります。

7
Hari

多分lockfileコマンドはあなたが必要とすることをするでしょう。

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

Unixでのみ実行している場合は、fifosを使用します。作業レコードをfifoに書き込み、このファイルからプロセスを読み取らせると、リーダーはfifoをブロックします。

ロックファイルは大丈夫ですが、あなたが説明するものについては私はfifosで行くでしょう

1
Chris

ここに投稿されているように、「 シェルスクリプトでの正しいロック? "、 FLOM(Free LOck Manager) ツールを使用して、コマンドとシェルスクリプトのシリアル化を実行するのと同じくらい簡単になります

flom -- command_to_serialize

FLOMでは、ここで説明するように、より洗練されたユースケース(分散ロック、リーダー/ライター、数値リソースなど)を実装できます。 http://sourceforge.net/p/flom/wiki/FLOM%20by %20examples /

0
tiian