1

シングルスレッドプロセスを使用していて、関連するシグナルがブロックまたは無視されていないことを前提とすると、次のことが保証されます。

kill(getpid(), sig);

次のコード行が実行される前に信号が配信されますか?

特に、シグナルがハンドラーがなく、デフォルトのアクション全体がプロセスを終了することである場合(SIGTERM、SIGALRMなど)、コードの次の行が実行されないことが保証されていますか?

私は常に(少なくともLinuxでは)答えは「はい」だと思っていました。なぜなら、システムコールから戻る前に、カーネルは保留中のシグナルがあるかどうかを常にチェックし、ある場合はそれらを配信すると思っていたからです。しかし、(高負荷のマルチコアシステムで実行した場合)これが常に当てはまるとは限りませんが、再現するのは非常に難しいので、何も表示されていないことを確認していただければ幸いです

[この質問は、killを使用して親スレッドに送信されるシグナルは、次のステートメントの前に処理されることが保証されていますか?と非常によく似ています。ただし、その質問はマルチスレッドプロセス(答えは間違いなく「いいえ」)について尋ねていましたが、この質問はシングルスレッドプロセスに関するものです。]

4

3 に答える 3

0

私は今、答えは本当に「はい」だと思います。以前は信号のブロックが解除されていると思っていましたが、そうではなかった可能性があり、これが私が見た動作の原因である可能性が高いことに気付きました。

于 2012-06-28T16:07:48.497 に答える
0

はい。シングルスレッドプロセスを使用している場合、POSIXはこれを保証します

pidの値により、送信プロセスに対してsigが生成され、呼び出し元のスレッドに対してsigがブロックされておらず、他のスレッドがsigのブロックを解除していないか、sigのsigwait()関数で待機している場合(sigまたは少なくとも) kill()が戻る前に、1つの保留中のブロックされていないシグナルが送信スレッドに配信されます。

于 2017-11-16T11:40:29.633 に答える
0

私はこのテストコードを作成しました:

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

sig_atomic_t suspended = 0;

void handle() {
    printf("SIG");
}

int main(int argc, char **argv) {
    signal(SIGUSR1, handle);
    printf("BEFO");
    kill(getpid(), SIGUSR1);
    //pthread_kill(pthread_self(), SIGUSR1);
    printf("AFTR\n");
    return 0;
}

また、4コアのラップトップでbashループで実行すると、常にBEFOSIGAFTRが出力され、BEFOAFTRSIGは出力されないようです。

ただし、テストにはいくつかの点でかなり欠陥があることに注意してください。

  • それが私のPCで機能するという事実は、それが保証されていることを意味するわけではありません(POSIXドキュメントに記載されていない限り)
  • テスト中、システムに大きな負荷がかかっていませんでした
  • STDIOはいくつかのバッファリングを行います
  • printf()はシグナルセーフではありません(man 7シグナルセーフティ)
于 2021-06-29T09:10:04.260 に答える