2016-09-01 9 views
0

アラーム信号を受信するまでプログラムをループで実行したいのですが、その間に割り込み信号を受信するたびにいくつかのコードを実行します。複数の割り込みをキャッチできません

次はほとんど機能します。

bool volatile waiting = true; 
bool volatile interrupted = false; 

void catch_interrupt(int x) 
{ 
    interrupted = true; 
} 

void catch_alarm(int x) 
{ 
    waiting = false; 
} 

void alive() 
{ 
    signal(SIGINT, catch_interrupt); 
    signal(SIGALRM, catch_alarm); 
    alarm(10); 

    while (waiting) 
    { 
     if (interrupted) 
     { 
      printf("interrupted\n"); 
      interrupted = false; 
     } 
    } 

    printf("done\n"); 
} 

問題はそれだけで最初の割り込み信号のために働くということです。 2番目の割り込みは、プログラムを強制終了します(「完了」を印刷することはありません)。私は、シグナルハンドラが信号に応答して呼び出されたときsignal()が解除されていると設定

^Cinterrupted 
^Cinterrupted 
done 

答えて

4

カスタムシグナルハンドラのインストールにはsignal()を使用しないでください。その場合の動作は実装によって異なります。特に、一部のシステムでは、signal()を使用して特定の信号用のカスタム信号ハンドラを設定すると、その信号が受信されるとその信号の配置がリセットされます。それはあなたが観察しているように見えますが、あなたはそれに移植可能に頼ることはできません。

代わりにsigaction()経由でシグナルハンドラをインストールしてください。とりわけ、シグナルの受信時にハンドラをリセットする必要があるかどうかを指定するメカニズムがあります。

2

シグナル・ハンドラを見たいとき

は、だから私は見出力は

^Cinterrupted 
^C 

です。それが第一の信号が処理された脆弱性の小さな窓があるが、第2の信号がプログラムの原因になりますと、ハンドラがまだ復活されていないことを意味、

void catch_interrupt(int x) 
{ 
    interrupted = true; 
    signal(SIGINT, catch_interrupt); 

} 

void catch_alarm(int x) 
{ 
    waiting = false; 
    signal(SIGALRM, catch_alarm); 
} 

はい:あなたは信号を毎回再武装する必要がシグナルハンドラがインストールされていないかのように反応します(シグナルハンドラがインストールされていないため)。

+0

ああ、私はそれほど疑わしい。これはどこに文書化されていますか? – Max

+0

@Max「man signal」を試してください。私の(Linuxの)マニュアルページでは、これについてはっきりと説明しています。 – unwind

+0

私は分かりません。私は古いHPワークステーションでコーディングしていた約18年前にこの問題に気がつきました。私たちは、シグナルの再活性化が我々が期待したことをしていることを理解しました。ニンジンとスティックで学ぶ:)そして、ジョンの答えはおそらく20歳ではないので、おそらくより良いです。 –

関連する問題