SIGCHLDを無視する場合もあれば、無視しない場合もあります

StackOverflow https://stackoverflow.com/questions/631641

  •  08-07-2019
  •  | 
  •  

質問

私のプログラムでは、ユーザーの入力に応じてfork()を数回行います。

場合によっては、SIGCHLDを処理し、「Process#Finished」のように言いたいことがあります。ただし、他のケースでは、この信号を無視したい。

これを行うにはどうすればよいですか

役に立ちましたか?

解決

シグナル処理は、プロセスに対してグローバルに設定されます。一部の子が終了し、他の子が終了しないときにSIGCHLDのような非同期信号をキャッチしたい場合、事前に一部の子を無視することはできません。

親で毎回信号を処理し、ハンドラーで無視するかどうかを決定する必要があります。

少なくとも、ハンドラーは子(siginfo_t構造体のsi_pid)でwait()を実行し、戻りコードを取得する必要があります。その時点で、プロセスIDを確認し、他に何をするかを決定できます。必要ない場合は何も印刷する必要はありません。

他のヒント

シグナルSIGCHLDをキャッチして、関数を呼び出します。これを行うには signal()を使用します( man signal )。以下の例では、シグナルSIGCHLDがキャッチされた後に child_died()が呼び出されます(この時点で子プロセスは停止しています)。子から親に child_died()が条件に必要な情報を渡す必要がある場合、パイプ( man pipe )を使用する必要があります。信号とパイプの例を次に示します。

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

#define MAX_SIZE 256

void child_died(int);

int fd[2];

int main()
{
    int pid;
    extern int fd[];
    char *str;

    pipe(fd);
    signal(SIGCHLD, child_died);

    if ((pid = fork()) < 0) {
        // error
        printf("Error\n");
    } else if (pid == 0) {
        // child
        printf("In child process\n");
        close(fd[0]);
        str = strdup("Message from child process.\n");
        write(fd[1], str, strlen(str) + 1);
    } else {
        // parent
        wait();
        printf("Now in parent\n");
    }

    return 0;
}

void child_died(int s)
{
    char *str;
    close(fd[1]);
    read(fd[0], str, MAX_SIZE);
    printf("%s", str);
}

sigchld.cとして保存し、次のコマンドでコンパイルします: gcc -Wall sigchld.c -o sigchld

int(子pidなど)または他のデータ型を子プロセスから親プロセスに渡す場合は、文字列に変換してから元に戻すか、別の方法を見つける必要がありますそれ。

SIGCHLDを無視したい場合、私の例では、そのロジックを child_died()に入れます。単純な if を使用するだけです。信号を無視するタイミングと、必要なものを印刷するタイミングをどのように決定しているかわからないので、上記のコードにパイプを含めました。子プロセスからの情報を使用すると考えました。 child_died()は親プロセスで呼び出されるため、子プロセスから親プロセスにデータを転送する方法が必要になります。

これが役立つことを願っています。これを達成するためのより良いまたはより簡単な方法があるかもしれませんが、私は知りません。ある場合はコメントしてください。

waitpid 関数をブロックモードまたは非ブロックモードで使用して、指定された子からの信号を待ってから処理を行うことができます。実際、Grahamの答えに記載されているように、何らかの wait を使用する必要があります ...

SIGCHLDを無視すると、プロセステーブルはゾンビでいっぱいになります。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top