2016-09-05 5 views
1

私はMac OS上で私のCプログラムを実行します。私のプログラムの一部は以下の通りです。このコードはsigintシグナルでうまく動作しますが、sigkillシグナルでは動作しません。私はprintfのから見ることができ、それは関数SIGINT()を入力し、フラグの値を変更することができ、私はsleep(1)を書いていないまずCで、linux、signalについてkillとloop()でsleep()

  1. void sigkill(int sig){ 
        /*some code neglected*/ 
        exit(0); 
    } 
    void sigint(int sig){ 
        flag=1; 
    } 
    
    void alive(void) { 
        signal(SIGINT, sigint); 
        signal(SIGKILL, sigkill); 
        alarm(10); 
        while(1){ 
         //printf("%d\n",flag); 
         sleep(1); 
         if(flag==1){ 
          printf("no\n"); 
          flag=0; 
         } 
        } 
    } 
    

    は、私は4つの質問を持っています。しかし、私は期待どおりに "いいえ"出力はありません。

  2. スリープ機能を追加した後、正常に機能します。 whileループは1秒ごとにフラグをチェックし、フラグ= 1なら "no"を出力すると仮定します。しかし、Ctrl + cを押すたびに「いいえ」と表示されるようです。なぜ1秒待たないのですか?

  3. 質問は「あなたは10秒を待つように 『睡眠を()』を使うべきではありません。アラーム()を使用し、ループに結合された。」と述べました私はsleep()なしでこれを実装する方法を知りたい。

  4. killコマンドはsigkill関数を呼び出せません。どのように修正するのですか?一般的に

+3

「SIGKILL」期間をトラップすることはできません。 'SIGKILL'のトラップを設定することはできません。偶然にも 'SIGSTOP'と同じです。 –

+0

あなたはsleep()を使わないでそれを実装する方法を知っていますか? –

+0

'alarm()'と 'sleep()'を混ぜることは100%信頼できません。それが中断し、シグナルハンドラ戻っているときにのみ返す '一時停止()' - あなたは 'アラーム()'と 'ポーズ()'を使用することができます。あなたは、サブ秒が眠る行うには() 'と'ポール() 'とプラットフォーム固有のバリアントを選択する'使用することができます。あなたが 'にnanosleep()'と 'はusleepを使用することができます()'眠っナノ秒とマイクロ秒の解像度を行うには(精度は一般的に解像度ほど良好ではないが)。あなたが一生懸命見ていると、どこかに何百分もの睡眠があります。 –

答えて

3
  1. 、信号は、それがカーネルにシステムコールを行うと、アプリケーションによって「キャッチ」することができます。平文をwhile(1) { if (flag==1){...} }にすると、決してカーネルを呼び出すことはありません。理論的には、あなたが外側のprintfwhile(1)ループで実行すると、カーネルが呼び出され、シグナルが捕捉される可能性があります。
  2. sleep()はいずれの信号によっても中断されます。マニュアルページでsleep(3)を確認してください。
  3. alarm(2)のマニュアルページを確認してください。
  4. SIGKILLまたはSIGSTOPのシグナルハンドラを変更することはできません。これらの信号効果はカーネルにハードコードされています。 sigaction(2)から:

    シグナム信号を指定し、SIGKILLSIGSTOPを除く任意の有効な信号であってもよいです。

    引数なしのkillコマンドは、SIGKILLシグナルを生成しません。 SIGTERMを生成します。

+0

私は第3の答えを本当に理解していません。それを睡眠なしに実装する方法は? 'アラーム(2)'のmanページから –

+1

: 'アラームは、()秒にプロセスに配信されるSIGALRM信号を手配seconds.' –

関連する問題