Domanda

Nel mio programma, fork () più volte a seconda dell'input dell'utente.

In alcuni casi, voglio gestire SIGCHLD e dire qualcosa come "Process # Finished". In altri casi, tuttavia, voglio ignorare questo segnale.

Come posso farlo?

È stato utile?

Soluzione

La gestione del segnale è impostata a livello globale per il processo. Se vuoi catturare un segnale asincrono come SIGCHLD quando alcuni bambini terminano ma non altri, non puoi decidere di ignorarlo per alcuni in anticipo.

Dovrai gestire il segnale ogni volta nel genitore, quindi decidere se vuoi ignorarlo nel gestore.

Come minimo, il gestore deve fare un wait () sul figlio (si_pid nella struttura siginfo_t) per raccogliere il suo codice di ritorno. A quel punto puoi controllare l'ID del processo e decidere cos'altro fare. Non è necessario stampare nulla se non si desidera.

Altri suggerimenti

Si desidera catturare il segnale SIGCHLD e quindi chiamare una funzione. Si desidera utilizzare signal () per fare questo ( man signal ). Nell'esempio seguente child_died () viene chiamato dopo che il segnale SIGCHLD viene catturato (il processo figlio è morto a questo punto). Se ci sono informazioni che devi passare dal figlio al genitore di cui child_died () ha bisogno di un condizionale, dovrai usare una pipe ( man pipe ) . Ecco un esempio di segnale e 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);
}

Salvato come sigchld.c e compilato con: gcc -Wall sigchld.c -o sigchld

Se vuoi passare un int (come il child pid) o qualche altro tipo di dati dal processo figlio al processo genitore, dovrai convertirlo in una stringa e viceversa o trovare un altro modo di fare esso.

Se vuoi ignorare SIGCHLD, nel mio esempio inseriresti quella logica in child_died () . Usa semplicemente un if . Non so come stai decidendo quando ignorare il segnale e quando stampare ciò che vuoi, ecco perché ho incluso le cose della pipe nel mio codice sopra. Ho pensato che avresti usato alcune informazioni dal processo figlio e poiché child_died () è chiamato sul processo genitore, avrai bisogno di un modo per trasferire i dati dal processo figlio a quello genitore.

Spero che questo aiuti. Potrebbero esserci modi migliori o più facili per ottenere ciò che non conosco. Se ci sono, si prega di commentare.

È possibile utilizzare la funzione waitpid in modalità bloccante o non bloccante per attendere il segnale da un determinato figlio e quindi eseguire alcune elaborazioni. In effetti, devi utilizzare wait in qualche modo, come è indicato nella risposta di Graham ...

Se ignori SIGCHLD, la tabella dei processi si riempirà di zombi.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top