0

さまざまな動作をループし、60 秒間スリープしてから、もう一度実行する while(1) スクリプトがあります。このスクリプトは、24 時間年中無休で実行する必要があります。

while(1) ループ内に新しい機能を追加したり、ランダムな問題の途中で追加したりすると、失敗してスクリプト全体がクラッシュすることがあります。解決策はそのような関数を eval{} でラップすることですが、私の質問は...すべてのエラーまたは致命的なエラーがスクリプト全体を停止/強制終了しないようにグローバルに設定する方法はありますか? eval{} ?

4

3 に答える 3

3

それは意味がありません。プログラムは再開する場所をどのように知るのでしょうか? 場所を指定する必要があり、 を使用してそれを行いますeval

失敗をログに記録してスクリプトを再起動するスクリプトのラッパーを作成することをお勧めします。

于 2013-09-05T14:32:49.267 に答える
3

あなたがやろうとしていること - エラーを無視し、どんな犠牲を払っても続行する - は非常に疑わしい慣行であり、プログラムを未定義の状態にする可能性があり、実際のバグを見つけるのをさらに難しくします.

理論的には、サブルーチンをオーバーライドして Perl コードからの例外をキャッチすることもできますが、実数は引き続きサブルーチンとして使用でき、これは XS コードまたは perl 自体からのエラーをトラップしません (を使用する場合とは異なります)。一部のモジュールでは制御フローにandが使用されることに注意してください。次のコードを検討してください。CORE::GLOBAL::diedieCORE::dieevaldiewarn

sub foo {
  my ($x, $y) = @_;
  croak "X must be smaller than Y" unless $x < $y;
  return $y - $x;
}

dieが になると、warnその関数は負の数を出力し始め、あらゆる種類の大混乱を引き起こします (たとえば、配列インデックスに使用された場合) 。

解決策をそのまま使用evalするか、さらに良いことに、に移行してくださいTry::Tiny。致命的なエラーには理由があります。


高い信頼性が必要な場合は、Erlang に似たモデル (ワーカー プロセスのプール) を採用することをお勧めします。エラーが発生した場合、そのプロセスは強制終了され、代わりのプロセスが開始されます。

于 2013-09-05T14:33:05.520 に答える