2

私は Linux プログラミングの初心者です。本から以下のコードをコピーしました。

#include <signal.h>
#include <stdio.h>
#include <unistd.h>

void ouch (int sig)
{
    printf("OUCH! - I got signal %d\n", sig);
    (void) signal(SIGINT, SIG_DFL);
}

int main ()
{
    (void) signal(SIGINT, ouch);

    while(1)
    {
        printf("Hello World!\n");
        sleep(1);
    }

}

が入力されたときに何かを出力することが期待されていましたCtrl+Cが、 print しか実行しませんHello World!


編集:Ctrl+Cをのショートカット キーとして バインドしたことをお詫び申し上げますcopy。ご迷惑をおかけしました。

4

3 に答える 3

2

私の提案はprintf、信号ハンドラー ( ouch ) で使用しないことです。未定義の動作である可能性があります。Async-signal-safe functions: シグナル ハンドラーのマニュアル ページで呼び出すことができる安全な関数のリスト

シグナル ハンドラ内から printf などのすべての関数を呼び出すのは安全ではありません。便利な手法は、シグナル ハンドラを使用してフラグを設定し、メイン プログラムからそのフラグをチェックして、必要に応じてメッセージを出力することです。

参照: Beginning Linux Programming, 4th Edition、この本ではコードが正確に説明されています。第 11 章: プロセスとシグナル、484 ページ

追加の役立つリンク:
説明:再入可能関数を使用して、より安全なシグナル処理を行う

于 2013-01-18T13:16:57.477 に答える
1

申し訳ありませんが、ここに質問が表示されません...でも、あなたが何に興味を持っているかは推測できます。

printf() はステートフル関数であるため、再入可能ではありません。状態を維持するために FILE 構造 (変数名は「stdin」) を使用します。(これは fprintf(stdin,format,...) を呼び出すようなものです)。

つまり、実装と「運」に応じて、シグナル ハンドラーから printf() を呼び出すと、期待どおりに出力される可能性がありますが、何も出力されないか、クラッシュするか、さらに悪いことに、メモリが破壊される可能性があります。なんでも起こる可能性がある。

したがって、明示的に「シグナルセーフ」とマークされていないシグナルハンドラー内から関数を呼び出さないでください。長期的には多くの頭痛を避けることができます。

于 2013-01-18T13:50:26.393 に答える
0

fflush(stdout)をシグナルハンドラに入れます。バッファリングされたばかりで、バッファがフラッシュされる前に 2 番目の SIGINT がプログラムを終了しました。

于 2013-01-18T13:19:37.160 に答える