2012-03-03 5 views
5

コードで動作していない。のprintfは(最小の場合)最初の質問にCシグナルハンドラ

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

int counter = 0; 

void react_to_signal(int n) { 
    fprintf(stderr, "Caught!\n"); 
    counter++; 
} 

int main(int argc, char** argv) { 

    signal(SIGINFO, react_to_signal); 

    while (1) { 
     printf("%d\n", counter); 
    } 

    return 0; 
} 

Iコードを実行する、それが別のシェルで次に0をプリントアウト、それが必要としてループ..

kill -s SIGINFO <pid_of_my_process> 

信号が配信されると、cが増加しますが、fprintfは発生しません。

これはなぜですか?どの環境/コンテキストでハンドラコードが実行されますか?どこでこれを読むことができますか?

+0

'fflush(stderr) 'を使用してstderrをフラッシュしようとしてください。 – Saphrosit

+2

printf()et.alを使用しないでください。内部シグナルハンドラ。彼らはシグナルセーフではありません(例えば、シグナルセーフではないmalloc()を呼び出すことができます)。 – wildplasser

+0

面白いことに、私が投稿した前に、fflushで変種を試していたと私は誓っていました。再コンパイルして実行したり、無限ループでメッセージを画面外に移動したりして、自分自身を足で撃ったことはありません。だから無気力で、ばかな。 – ntl0ve

答えて

14

:あなたは

非同期シグナル安全セクションで、シグナルハンドラのmanページでlist of authorized functionsありますシグナルハンドラ内安全のprintfを使用することはできません。そこにfprintfはありません。

この関数は、ののリエントラントではないため、主にmallocとfreeを使用できるためです。 詳細については、this postを参照してください。

+0

を参照してください。どうもありがとう! – ntl0ve

1

プログラムが終了する前にメッセージを書き込むには、stderrをfflushする必要があります。

要するに
+0

改行に達すると 'printf'は自動的にフラッシュされませんか? –

+1

いいえ、https://stackoverflow.com/questions/5229096/does-printf-always-flush-the-buffer-on-encountering-a-newline –

関連する問題