2010-11-22 11 views
0

Ich möchte wissen, wann mein Kindprozess beendet wird. Aber ich möchte meine Anwendung nicht blockieren, also verwende ich WNOHANG.Falscher Status während der Verwendung von waitpid mit WHOHANG

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

void handler(int nsig) { 
    int status; 
    waitpid(-1, &status, WNOHANG); 
    printf("nsig=%i; status=%i\n", nsig, status); 
    if (WIFEXITED(status)) { 
    printf("Exited\n"); 
    } 
} 

int main() { 
    struct sigaction act; 
    act.sa_handler = handler; 
    if (sigaction(SIGCHLD, &act, 0) < 0) { 
    fprintf(stderr, "sigaction failed\n"); 
    exit(-1); 
    } 

    pid_t fpid; 
    fpid = fork(); 
    if (fpid == 0) { 
    execlp("okular", "okular", 0); 
    } 
    while(1); 
    return 0; 
} 

Es funktioniert gut, wenn ich "okular" wie üblich schließen.

$ ./test 
nsig=17; status=0 
Exited 

Aber wenn ich etwas tun, wie

kill -STOP OKULAR_PID 

habe ich die gleiche Leistung und das ist falsch für mich, weil okular in der Tat nicht Ausfahrt tat.

+0

Das ist nicht Ihr Problem, aber Sie sollten wissen, dass der Aufruf von 'printf' aus einem Signalhandler normalerweise zu undefiniertem Verhalten führt. –

+0

Vielen Dank für die Warnung. – Ximik

Antwort

1

Ich denke, es ist richtig, weil SIGCHLD definiert als Kind beendet oder gestoppt wie in diesem Signal zu sehen ist. SIGCLD ist ein Synonym für SIGCHLD.

+0

Aber warum funktioniert WIFEXITED? – Ximik

+3

@Ximik: Sie sollten 'status' nur prüfen, wenn' waitpid() 'einen Wert'> 0' zurückgegeben hat. – caf

+0

Danke. Dies ist die Lösung. – Ximik

Verwandte Themen