2011-12-05 14 views
2

シグナルハンドラでブロックすることなく、すべての子と孫が終了するまでどのように待つことができますか?これはこれまでの私の試みです。あなたが必要なもの子どもと孫を待つ

#include <signal.h> 
#include <stdio.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/wait.h> 
#include <unistd.h> 

int run = 1; 

void handler(int sig, siginfo_t *info, void *uap) 
{ 
    int exit_code; 

    printf("sigchld pid %d\n", info->si_pid); 
    pid_t pid = waitpid(-1, &exit_code, 0); 
    if (pid == -1) { 
     perror("waitpid()\n"); 
    } else { 
     printf("waitpid returned %d\n", pid); 
    } 
    // set run = 0 when all children exit 

    printf("end of sigchild handler\n"); 
} 

void main() { 

    struct sigaction chld; 
    chld.sa_sigaction = handler; 
    chld.sa_flags = SA_NOCLDSTOP | SA_SIGINFO; 
    sigaction(SIGCHLD, &chld, NULL); 

    //procmask sigchld? 
    if (!fork()) { 
     if (!fork()) { 
      sleep(2); 
      printf ("grand-son exit: %d\n", getpid()); 
      exit (0); 
     } 
     sleep(1); 
     printf ("son exit: %d\n", getpid()); 
     exit (0); 
    } 

    while(run) 
     sleep(1); 

    printf("ciao\n"); 
} 
+3

孫を待つことはできません。子供が自分の子供を待たずに出かけると、それらの子供は通常、 "root"または "init"プロセスに再割り当てされます。 (http://en.wikipedia.org/wiki/Orphan_processを参照してください) – ruakh

+1

1)main returns int。 2)シグナルハンドラでprintf()を使用しないでください。 3)祖父母が祖父母プロセスから切り離すための方法です(ただし、端末(グループ)から切り離すためにいくつかの追加のシステムコールが必要な場合があります) – wildplasser

答えて

0

SIGCHLDとwaitpidなどは直系の子供のためにしか動作しませんが、UNIXシステムでは、親から子に渡された継承されたリソースを少しでも "不正に使う"ことができますプロセス終了時に閉じます。

たとえば、元のプロセスはpipeを開き、おそらくを設定するかもしれない子供や孫が書き込み終了を継承するように、それclose-on-exec終わりをお読みください。元のプロセスがすべての子孫が終了するのを待つ準備ができたら、パイプの書き込み終了を閉じて残りのディスクリプタを読みやすくするためにブロックreadまたはselectをブロックします。最後の子孫が終了すると、パイプの読み込み側がEOFを返します。

この方法は保証されていません。子供または孫が継承したファイル記述子を慎重に閉じる可能性がありますが、しばしば十分に機能します。

0

はwait関数です: 待ち、waitpidを - 停止または終了するために子プロセスを待ちます。 編集:nope :)

+0

私はwaitpidを使用します。 – elmarco

関連する問題