2

フォルダーが存在しない場合 (または一貫性がない場合)、特定の場所から 1 つのフォルダーをコピーするスクリプトを実行しています。スクリプトを 2 回以上同時に実行すると、問題が発生します。最初のスクリプトがファイルをコピーしようとしているときに、2 番目のスクリプトが来て同じことを試み、混乱を招きます。どうすればこの状況を回避できますか? システム全体のミューテックスのようなもの。

で簡単なテストを試みまし-wた。フォルダーを手動でコピーし、フォルダーのコピー中にスクリプトを実行しました。

use strict;
use warnings;

my $filename = 'd:\\folder_to_copy';
if (-w $filename) {
  print "i can write to the file\n";
} else {
  print "yikes, i can't write to the file!\n";
}

もちろん、これは機能しません。そのフォルダーへの書き込みアクセスがまだ残っているからです。フォルダがコピーされているPerlか、使用されているかを確認する方法はありますbatch commandsか?

4

4 に答える 4

7

ロックファイルの仕事のように聞こえます。ロック ファイルを実装する CPAN モジュールは無数にありますが、それらのほとんどは Windows では動作しません。CPAN テスターに​​よると、Windows をサポートしていると思われるいくつかを次に示します。

ソースコードをざっと見た後、お勧めできる唯一のモジュールはFile::Flock::Tinyです。他の人は際どいようです。

于 2016-10-13T12:52:34.373 に答える
4

システム全体のミューテックスが必要な場合、1 つの「トリック」は、ディレクトリを (ab) 使用することです。コマンドmkdirは通常、アトミックであり、機能するか機能しないかのいずれかです (ディレクトリが既に存在する場合)。

スクリプトを次のように変更します。

my $mutex_dir = '/tmp/my-mutex-dir';
if ( mkdir $mutex_dir ) {

    # run your copy-code here

    # when finished:
    rmdir $mutex_dir;
} else {
    print "another instance is already running.\n";
}

確認する必要がある唯一のことは、/tmp(またはどこにでも) ディレクトリを作成できることです。

との間で他の誰かがディレクトリを作成する可能性があり、とにかく失敗するため、最初に の存在を意図的にテストしないことに注意してください。単純に を呼び出します。それが機能した場合は、自分のことを行うことができます。完了したら、忘れずに削除してください。$mutex_dirif (not -d $mutex_dir)mkdirmkdirmkdir$mutex_dir

これは、このアプローチの欠点でもあります。コピー コードがクラッシュし、スクリプトが途中で終了した場合、ディレクトリは削除されません。おそらく、 nwellnhof の回答で提案されているロック ファイル メカニズムは、その場合により適切に動作し、自動的にファイルのロックを解除します。

于 2016-10-13T12:50:55.580 に答える