0

私は、ファイルのセットを(一度に1つずつ)排他的にロックし、そのロックを一定時間(スリープを介して)保持しようとしているサブルーチンを持っています。ユーザーがEnterキーなどの特定のキーを押すたびに、現在のロックされた(スリープ状態の)ファイルのロックを解除できる機能を追加しようとしています。これを機能させるためにどの方向に進むべきかわかりません。STDINを使用して\nをチェックするすべての試みは機能していません。ありがとう。

以下はサブルーチンです。ファイルが必要なディレクトリに移動します。1から指定されたファイルの数までファイルを作成します。ファイルごとに排他ロックがかけられ、指定された時間スリープします。

編集:これについて言及しないのは私のせいですが、このスクリプトはWindows環境で実行されます。理想的には、Perlに含まれていない追加のモジュールのインストールを必要としないソリューションが欲しいです。(これは、breqwasのソリューションのモジュールがWindowsをサポートしていないために発生しました)。ありがとう。

sub lockFiles{
    #creates files that are locked for a specific amount of seconds.
    chdir("lock files")or die "Unable to enter dir $!\n";
    opendir(DIR,".") or die "Can't open the current directory: $!\n";

    #file iterator
    my $i=1;
    #for each file lock it and sleep the given amount of time
    while($i<=$numberOfFiles){
        open FILE, ">>", "test$i.txt" or die $!;
        flock(FILE, 2) or die "Could not lock test$i.txt\n";
        print "test$i.txt locked, locking for $timeToSleep seconds\n";
        print "Press ctrl+c to kill this\n";

        sleep($timeToSleep);

        $i++;
        close(FILE);
    }
    closedir(DIR);
    #change back to the parent folder
    chdir("..") or die "Can't change to the directory: $!\n";
    print "subRoutine lockFiles success\n";
}
4

2 に答える 2

1

私はそれが動作するかどうかを確認するための perl がインストールされた Windows マシンを持っていませんが、Term::ReadKey に関するドキュメントはそれが必要であることを暗示しています。Term::ReadKey は、非ブロッキングおよび時間指定読み取り機能を提供するモジュールです。一部の限定的な Windows サポートがあります。

use Time::HiRes qw(time sleep);
use Term::ReadKey;

sub wait_for_key {
    my $timeout = shift;

    my $started = time();
    while (1) {
        last if $started + $timeout < time();

        my $str = '';
        while (my $char = ReadKey(-1)) {
            $str .= $char;
        };

        last if $str =~ m/\n/s;
        sleep 0.1;
    }
}

ただし、それを行うためのより良い方法があると確信しています。perl-on-windows の経験がある人が現れるかもしれません。

のろい、Windows。他のシステムでは、上記のコードは次のようになります。

sub wait_for_key { ReadLine(shift) }
于 2012-05-16T01:49:39.580 に答える
0

そのように試してみてください:

use Sys::SigAction qw(sig_alarm set_sig_handler);

sub wait_for_key {
    my $timeout = shift;

    eval {
        my $sa = set_sig_handler('ALRM', sub { die "enough" }, {} );
        eval {
            sig_alarm($timeout);
            my $keyboard = <>;
            sig_alarm(0);
        };
        sig_alarm(0);
    }
}

この関数は、入力 (「Enter」キー) の後、またはタイムアウトによって終了するため、sleep() の代わりに呼び出すだけです。基本的な考え方は次のとおりです。

1)入力を無限に待ちます
2)必要なタイムアウトのアラームを設定します。

悪そうに見えますが、うまく機能します。

これは実際には、タイムアウトを指定してコードを呼び出す一般的な方法です。この関数に関数参照である 2 番目のパラメーターを受け入れさせ、my $keyboard = <>行の代わりにその参照を呼び出すだけです。そして、まあ、エラーをチェックして、このサンプルで省略した退屈なことをすべて実行してください。

于 2012-05-14T22:20:01.903 に答える