8

Unix環境のAdvance Programmingからこのプログラムを試していました。

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

static void handler(int sig){
    if(sig == SIGUSR1)
        printf("handled user1 signal");
    else if(sig == SIGUSR2)
        printf("handles user2 signal");
    else
        printf("unkown signal");
}

int main(){

    if(signal(SIGUSR1, handler) == SIG_ERR)
        printf("can't handle signal SIGUSR1");
    if(signal(SIGUSR2, handler) == SIG_ERR)
        printf("can't handle signal SIGUSR2");
    for(;;)
        pause();
    return 0;
}

Ubuntu 11.10 を使用しています。gcc でプログラムをコンパイルし、本に示されているように a.out を実行します。

$./a.out& [1]+ 1345

$ kill -USR1 1345

しかし、印刷された出力はありません。プログラムはバックグラウンドで実行され続けるため、強制終了する必要があります。

私が試した他のこと:

  1. バックグラウンドで実行中のプログラムが問題を引き起こしているかどうかを確認するために、SIGINT の処理を​​試みました。まだ出力はありません。

  2. FreeBSD の最新リリースをダウンロードし、同じプログラムを試してみましたが、同じ問題がありました。

  3. シグナル ハンドラを設定する前に、printf ステートメントを挿入します。

    int main(){
        printf("printf is working...");
        //exit(0);
        if(signal(SIGUSR1, handler) == SIG_ERR)
        ...
    

exit() がコメント化されている場合、出力はありません。コメントを外すと、出力が印刷されます。

これで何が間違っているのか教えてください。

PS: sigaction() の使用はお勧めしません。私は Unix プログラミングを学んでおり、実用的なアプリケーションを構築していません。

4

1 に答える 1

15

からの出力printfはバッファリングされます。つまり、出力にフラッシュされるまでメモリに保存されます。テキストをフラッシュインする最良の方法printfは、テキストを改行で終了することです。関数を使用して手動でフラッシュすることもできfflushます。

ただし、シグナルハンドラーでは、およびのような出力関数を使用することは安全であるprintfとは見なされないことに注意する必要があります。fflush

于 2012-08-27T09:47:36.537 に答える