4

なぜこの単純なスクリプト:

#! perl -w

use strict;
use warnings;
$| = 1;

my $LOCKFILE = "$0.lock";

sub mklock {
    open my $lf, ">", $LOCKFILE;
    print $lf $$;
    close $lf;
}

sub rmlock { unlink $LOCKFILE; }

sub clean_exit { rmlock;  exit 0; }

sub work {
    print "working...";
    sleep 10;
    # although `sleep 1 foreach (1..10);`
    # *does* interrupt---between `sleep`s--see my answer
    print "done.\n"
}

$SIG{INT} = "clean_exit";

mklock;
work;
rmlock;

Debianで動作しますが、Windowsでは動作しませんか?

  • Windowsでは、このスクリプトが機能している場合、Ctrl+Cは無視されます
  • Debianでは、クリーンな終了が期待どおりに実行されます
  • を使用する$SIG{INT} = \&clean_exit;と、動作は同じように見えます
  • SIGHUP( ( )で同じことをすると$SIG{HUP} = "clean_exit";、ウィンドウは閉じられますが、とにかくクリーンな終了は実行されません)

(まあ、それperl 5, version 14, subversion 2 (v5.14.2) built for MSWin32-x86-multi-threadはWindows 7のStrawberryとDebian6.0.4perl, v5.10.1 (*) built for x86_64-linux-gnu-thread-multiボックスのamd64-vs-であることを認めますが、そのような基本的なものにとって重要ではないかと思います。編集: ActiveState perl 5.12の同様のボックスでチェックしたところ、同じです。 、そのため、問題はStrawberryに限定されていないようです。)

perlportがそれを明確に言っていることを私は知っています、

シグナルや%SIGを当てにしないでください。

しかし、方法があるに違いありません...(さらに、私は理解したいと思います。)

では、別の方法で何をすべきでしょうか?

4

3 に答える 3

4

sigtrapプラグマを使用できます。

use sigtrap 'handler', \&cleanup, 'normal-signals';

これにより、シグナルがキャッチされたときにメソッドが呼び出さcleanupれ、シグナルIDがパラメーターとして渡されます。

于 2012-06-06T10:47:57.770 に答える
1

DOSアプリケーションでunixlineの規律に従うことは贅沢であり、権利ではありません。

Ctrl+BreakCtrl+Cに相当するウィンドウであるに従う。

編集をCtrl+Breakに変更-これは私がMacキーボードを使用して得たものです。

割り込み処理をテストするために、work subで次のループを使用する必要があります。そうしないと、ハンドラーをトリガーする前に、スリープ全体が完了するまで待機します。

sub work {
    print "working...";
    my $i = 0;
    while ($i < 10) {
       sleep(1);
       $i--;
    }
    say "done."
}

このようにして、キー押下をより簡単に検出できます。スリープの進行中は、割り込み処理は検出されません。

私を混乱させてください-INTハンドラーは現在機能しています!

編集perlの生のソースコードは、ウィンドウを閉じるイベントとしてHUPをサポートする必要があると主張していますが、CMDウィンドウを閉じるをクリックするとイベントが配信されないようです

于 2012-06-06T10:34:59.357 に答える
1

さらにいくつかのprintingを追加した後、実際には、コード機能することを発見しました。ただし、の間は中断しませんsleep

したがってsleep 60、より「現実的な」ものに変更するだけで、sleep 1 foreach (1..10);はるかに許容できる動作がもたらされます。

もちろん、Windowsと*nixでは動作が異なります。

于 2012-06-06T11:20:54.620 に答える