2009-03-10 9 views

Antwort

4

Die Signalverarbeitung ist global für den Prozess eingerichtet. Wenn Sie ein asynchrones Signal wie SIGCHLD abfangen wollen, wenn einige Kinder nicht aber andere beenden, können Sie nicht entscheiden, es für einige im Voraus zu ignorieren.

Sie müssen das Signal jedes Mal im Parent verarbeiten und dann entscheiden, ob Sie es in Ihrem Handler ignorieren möchten.

Zumindest sollte Ihr Handler eine wait() auf das Kind (si_pid in der siginfo_t-Struktur) warten, um seinen Rückkehrcode zu ernten. An diesem Punkt können Sie die Prozess-ID überprüfen und entscheiden, was Sie sonst tun möchten. Sie müssen nichts drucken, wenn Sie nicht möchten.

0

Wenn Sie SIGCHLD ignorieren, wird die Prozesstabelle mit Zombies gefüllt.

+0

In einigen Varianten von Unix, Ignorieren SIGCHLD automatisch die untergeordneten Prozesse (scheinbar). http://www.faqs.org/faqs/unix-faq/faq/part3/section-13.html –

2

Sie können die Funktion waitpid entweder im blockierenden oder im nicht blockierenden Modus verwenden, um auf das Signal von einem bestimmten Kind zu warten und dann eine Verarbeitung durchzuführen. In der Tat, Sie haben wait irgendeiner Art zu verwenden, wie es in Grahams Antwort angegeben ...

3

Sie möchten das Signal SIGCHLD fangen und dann eine Funktion aufrufen. Sie möchten dazu signal() verwenden (man signal). Im folgenden Beispiel wird aufgerufen, nachdem das Signal SIGCHLD abgefangen wurde (Child-Prozess ist zu diesem Zeitpunkt tot). Wenn es Informationen gibt, die Sie von dem untergeordneten Element an das übergeordnete Element übergeben müssen, das für eine Bedingung benötigt, müssen Sie eine Pipe verwenden (man pipe). Hier ist ein Beispiel von Signal und Rohr:

#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); 
} 

Gespeichert als sigchld.c und kompilierte mit: gcc -Wall sigchld.c -o sigchld

Wenn Sie einen int übergeben wollen (wie das Kind pid) oder einen anderen Datentyp aus dem Kind-Prozess in den Elternprozess müssen Sie entweder in eine Zeichenfolge und wieder zurück konvertieren oder finden Sie eine andere Möglichkeit, es zu tun.

Wenn Sie SIGCHLD ignorieren möchten, dann würden Sie in meinem Beispiel diese Logik in setzen. Verwenden Sie einfach eine einfache if. Ich weiß nicht, wie Sie entscheiden, wann Sie das Signal ignorieren und wann Sie drucken sollen, was Sie wollen, deshalb habe ich die Pipe-Sachen in meinen obigen Code aufgenommen. Ich dachte, dass Sie einige Informationen aus dem Child-Prozess verwenden würden, und da im übergeordneten Prozess aufgerufen wird, benötigen Sie eine Möglichkeit, Daten vom untergeordneten zum übergeordneten Prozess zu übertragen.

Ich hoffe, das hilft. Es kann bessere oder einfachere Wege geben, dies zu erreichen, von denen ich nichts weiß. Wenn es dann kommentieren Sie bitte.

Verwandte Themen