6

Linuxサーバーでは、BASHとPHPで記述された複数のスクリプトを同期する必要があります。これにより、システムクリティカルなジョブ(一連のBASH / PHPコマンド)を開始できるのはそのうちの1つだけになり、 2つ以上のスクリプトによって同時に実行されます。C ++でのマルチスレッドの経験から、ミューテックスの概念に精通していますが、別々のプロセスで実行され、もちろんC ++で記述されていない一連のスクリプトにミューテックスを実装するにはどうすればよいですか?

頭に浮かぶ最初の解決策は、各スクリプトが最初に「ロックフラグ」ファイルを作成して、ジョブが「ロック」されていることを他のスクリプトに通知し、ジョブの完了後にファイルを削除することです。しかし、私が見ているように、このアプローチを100%の確率で機能させるには、ファイルの書き込み読み取りの操作が完全にアトミックである必要があり、同じ要件が他の同期方法にも当てはまります。そして、ファイルの書き込み/読み取り操作はアトミックではなく、少なくとも既存のすべてのLinux/Unixシステムではアトミックではないと確信しています。

では、BASHスクリプトPHPスクリプトを同時に同期するための最も柔軟で信頼性の高い方法は何でしょうか。

4

3 に答える 3

2

私はPHPプログラマーではありませんが、ドキュメントには、flock使用できるポータブルバージョンが提供されていると記載されています。最初の例のスニペットは、必要なものにかなり近いように見えます。これを試して:

<?php

$fp = fopen("/tmp/lock.txt", "r+");

if (flock($fp, LOCK_EX)) {  // acquire an exclusive lock

    // Do your critical section here, while you hold the lock

    flock($fp, LOCK_UN);    // release the lock
} else {
    echo "Couldn't get the lock!";
}

fclose($fp);

?>

デフォルトflockでは、ロックを取得できるまで待機することに注意してください。LOCK_EX | LOCK_NBプログラムの別のコピーがすでに実行されている場合にすぐに終了したい場合に使用できます。

「/tmp/lock.txt」という名前を使用することはセキュリティホールである可能性があります(本当にそうかどうかを判断するのに十分なほど考えたくありません)。したがって、プログラムでのみ書き込み可能なディレクトリを選択する必要があります。

于 2012-11-10T06:52:24.227 に答える
1

flockを使用して、フラグファイルをアトミックにロックできます。-eオプションは、排他ロックを取得することです。

マニュアルページから:

デフォルトでは、ロックをすぐに取得できない場合、flockはロックが使用可能になるまで待機します。

したがって、すべてのbash / phpスクリプトがファイルを排他的にロックしようとすると、1つだけが正常にファイルを取得でき、残りのスクリプトはロックを待機します。

待ちたくない場合は-w、タイムアウトを使用してください。

于 2012-11-07T11:16:57.713 に答える
0

Bashのフューザーベースのロック(2つのプロセスが同時に保護されたリソースにアクセスしないことを保証しますが、リソースにアクセスするプロセスがない場合でも、ネガティブロックの試みが発生する可能性がありますが、ほとんどありません):

#!/bin/bash
set -eu
function mutex {
 local file=$1 pid pids
 exec 8>>"$file"
 { pids=$(/sbin/fuser -f "$file"); } 2>&- 9>&-
 for pid in $pids; do
   [[ $pid = $$ ]] && continue
   exec 8>&-
   return 1 # locked by other pid
 done
}
于 2012-11-07T13:12:22.527 に答える