fork()およびシグナルがプロセスに配信される方法


13

私は、C fork()で子プロセスから作成したプログラムを作成します。どちらのプロセスも終了しません。コマンドラインからプログラムを起動してcontrol-cを押すと、どのプロセスが割り込み信号を受信しますか?

回答:


20

試してみてみませんか?これは、親プロセスと子プロセスの両方signal(3)をトラップSIGINTし、プロセスが到着したときにそれを識別するメッセージを出力するために使用する簡単なプログラムです。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
void parent_trap(int sig) {fprintf(stderr, "They got back together!\n");}
void child_trap(int sig) {fprintf(stderr, "Caught signal in CHILD.\n");}
int main(int argc, char **argv) {
    if (!fork()) {
        signal(SIGINT, &child_trap);
        sleep(1000);
        exit(0);
    }
    signal(SIGINT, &parent_trap);
    sleep(1000);
    return 0;
}

それを呼び出しましょうtest.c。これで実行できます:

$ gcc test.c
$ ./a.out
^CCaught signal in CHILD.
They got back together!

端末で生成された割り込み信号は、アクティブなプロセスグループに配信されます。ここには、親と子の両方が含まれます。あなたは、両方のことを見ることができるchild_trapとはparent_trap、私が押されたときに実行されましたCtrl- C

POSIXの相互作用forkとシグナルに関する長い議論があります。ここで最も重要な部分は次のとおりです。

fork()の後にプロセスグループに送信されるシグナルは、親と子の両方に配信される必要があります。

彼らはまた、特に信号が時刻の非常に近くに到着するとき、いくつかのシステムが正確に正しい方法で振る舞わないかもしれないことに注意しますfork()。これらのシステムの1つを使用しているかどうかを判断するには、おそらく個々の試行で相互作用がほとんど発生しないため、コードを読むか、または多くの運が必要になります。

その他の便利な点は次のとおりです。

  • 手動で生成され、個々のプロセス(おそらくkill)に送信されるシグナルは、親か子かに関係なく、そのプロセスにのみ配信されます。
  • シグナルハンドラーがプロセス間で実行される順序は定義されていないため、どちらを最初に実行することに依存することはできません。
  • 割り込みハンドラを定義しない場合(または明示的にシグナルを無視する場合)、両方のプロセスはSIGINTコード(デフォルトの動作)で終了します。
  • 一方がシグナルを非致命的に処理し、もう一方が処理しない場合、ハンドラーのない方が死に、もう一方が続行します。

シェルも興味深い方法で干渉できると思いますか?彼らがトラップできる信号である場合、それはその子に送信される可能性がありますか?(そして、SIGHUPがあります)(これのすべてが... OSが信号を送信しない一方で、子プロセスは親への信号の影響を受けないではないかもしれないということを意味するかもしれませんが)
ゲルトバンデンベルグ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.