3

C で開発されたプログラムがあります。プログラムを終了する前にいくつかの C コードを実行するために、このプログラムに sigaction ハンドラを追加しました。

void signal_term_handler(int sig)
{
    printf("EXIT :TERM signal Received!\n");
    int rc = flock(pid_file, LOCK_UN | LOCK_NB);
    if(rc) {
        char *piderr = "PID file unlock failed!";
        fprintf(stderr, "%s\n", piderr);
        printf(piderr);
    }
    exit(EXIT_SUCCESS);
}

int main(int argc, char **argv)
{
    struct sigaction sigint_action;

    sigint_action.sa_handler = &signal_term_handler;
    sigemptyset(&sigint_action.sa_mask);

    sigint_action.sa_flags = SA_RESETHAND;
    sigaction(SIGTERM, &sigint_action, NULL);
        ...........
}

注:私のプログラムには、実行中の2つのサブスレッドが含まれています

myprogram を実行してから、プログラムを強制終了するために呼び出しますkill -15 <pidnumber>。メッセージ"EXIT :TERM signal Received!\n" stdout に出力されますが、プログラムは終了しません。

sigaction コードに何か不足していますか?

4

3 に答える 3

4

exit()必ずしも async-signal safe であるとは限りません。

シグナル ハンドラから直接プロセスを終了するには、 または のいずれ_exit()かを呼び出しますabort()


flock()また、関数ファミリーのすべてのメンバーprintfも async-signal-save ではありません。


async-signal-safe 関数の完全なリストについては、ここをクリックしてください

于 2013-06-06T15:51:17.050 に答える
2

flock()受信時にファイルを un- しようとする XY 問題があるのではないかと私はまだ思っていますSIGTERM

これを達成するには (そしてこれにより、シグナル受信で async-signal-safe 関数のみを使用できるという制限を回避するには、次のアプローチを使用します。

  • アプリがメイン スレッドで処理するすべてのシグナルをマスクします。
  • スレッドを作成します。
  • スレッドのシグナル マスクを変更して、このスレッドが処理対象のすべてのシグナルを受信するようにします。
  • このスレッドsigwaitinfo()では、シグナルを受信して​​ディスパッチするためにループします。
  • 次に、このスレッドによって受信されたシグナルに応じて、関数の async-signal-saftyness が欠落しているため、制限なしで実行する必要があることを行います。
于 2013-06-07T08:33:00.313 に答える
1

おそらくこれは、シグナル ハンドラで多くのことを行うことが実際には許可されていないためです (ライブラリ関数の呼び出しは確かに大ざっぱです)。

このような処理を行う通常の方法は、シグナル ハンドラが変数を設定するか、通常のメイン ループが処理するイベントをキューに入れ、終了することです。

于 2013-06-06T15:47:42.753 に答える