0

さまざまなコマンドを実行するコンソールプログラムがあります。プログラムの複数のインスタンスを並行して実行できるようにしたいのですが、特定のコマンドが並行して処理されないようにしたいのです。

シンプルなファイルロックシステムを考えました。

与えられたコマンド「foo」を並行して実行することは許可されていませんが、それは機能しますか?

  1. fooを実行する前に、ファイル.lock_foo_ *が存在するかどうかを確認します(存在する場合は中止します)
  2. そうでない場合は、ファイル.lock_foo_GUIDを作成します
  3. .lock_foo_GUIDが存在するかどうか、および他の.lock_foo_*ファイルが存在しないかどうかを確認します

別の.lock_foo_*ファイルがある場合、それは別のインスタンスが同時に1つを作成し、ロックファイルを中止して削除することを意味します。

競合状態があるかどうか、そしてそれがそれを処理する正しい方法であるかどうか疑問に思いますか?

アップデート

実際には、当初の予想よりも簡単だと思います(少なくともWindowsでは)。バーツからの回答が私を正しい方向に導いたと思います。

私はこのようなものがうまくいくはずだと思います

public bool CreateLock(string fileName){
     try{
         File.Open(string.Format(".lock_{0}",fileName), FileMode.Create, FileAccess.ReadWrite, FileShare.None);
      }
      catch (Exception exception){
           return false;
      }
      return true;
}

OSは、ファイルがまだ存在しない場合にのみファイルが作成されることを確認し、そうでない場合は例外を発生させます。したがって、この方法は安全なはずです。残念ながら、これはUNIXでは機能しません。

4

1 に答える 1

0

あなたの論理はかなり良さそうです。ただし、興味がある場合は、たとえばlockfile、など、必要なことを実行するコマンドラインユーティリティがすでに複数存在しますflock

試してみてくださいman 1 lockfile。そのマンページがあなたの質問に簡潔に答えると思います。

一方、これを自分で実装する必要がある、または実装したい場合は、提案するアプローチはほぼ正しいですが、散発的に失敗することがあります。これは苛立たしいことですが、あなたがやろうとしていることの種類に固有のものです。その理由は、(1)別のプロセスがリソースをロックしているかどうかを確認することと(2)リソースをロックすることの間に短い間隔が介在するためです。この短い間隔の間に、別のプロセスがリソースをロックする必要がある場合はどうなりますか?

必要なのはアトミック操作です。これは、単一の中断できないステップとして何らかの形でチェックおよびロックします。幸いなことに、最新のCPUはそのような不可分操作を提供し、最新のオペレーティングシステムカーネルはそれらを公開します。そのため、実際に必要なことを確実に実行できます。

これに興味がある場合は、LockFileおよびLockFileExに関するMicrosoftの開発ドキュメントを参照してください。

于 2012-06-05T14:05:29.880 に答える