Pergunta

No meu programa, eu fork () várias vezes dependendo de entrada do usuário.

Em certos casos, eu quero lidar com SIGCHLD e dizer algo como "Processo # terminado". Em outros casos, porém, eu quero ignorar este sinal.

Como posso fazer isso?

Foi útil?

Solução

manuseio

Signal está configurado globalmente para o processo. Se você quiser pegar um sinal assíncrono como SIGCHLD quando algumas crianças terminar, mas não outros, você não pode decidir ignorá-la por alguma antecedência.

Você vai precisar para lidar com o sinal de cada vez no pai, em seguida, decidir se deseja ignorá-lo no seu manipulador.

No mínimo, o manipulador deve fazer uma wait () sobre a criança (si_pid na estrutura siginfo_t) para colher seu código de retorno. Nesse ponto, você pode verificar o ID do processo e decidir o que fazer. Você não tem que imprimir qualquer coisa se você não quiser.

Outras dicas

Você quer pegar o SIGCHLD sinal e, em seguida, chamar uma função. Você quer usar signal() para fazer isso (man signal). No exemplo abaixo child_died() é chamado após o SIGCHLD sinal é capturado (processo filho é morta neste ponto). Se há uma informação que você precisa para passar da criança para o pai que as necessidades child_died() para uma condicional, você vai precisar usar um tubo (man pipe). Aqui está um exemplo de sinal 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);
}

salvo como sigchld.c e compilado com: gcc -Wall sigchld.c -o sigchld

Se você quer passar um int (como o pid criança) ou algum outro tipo de dados a partir do processo filho para o processo pai você quer vai ter que convertê-lo em uma corda e de volta ou encontrar outra maneira de fazer -lo.

Se você quiser ignorar SIGCHLD seguida, no meu exemplo, você iria colocar essa lógica em child_died(). Basta usar um simples if. Eu não sei como você está decidindo quando a ignorar o sinal e quando para imprimir o que você quer, é por isso que eu incluído o material de tubo no meu código acima. Imaginei que você usaria algumas informações do processo filho e desde child_died() é chamado no processo pai, você vai precisar de uma maneira de transferir dados a partir da criança a processo pai.

Espero que isso ajude. Pode haver melhor ou mais fácil maneiras de se conseguir isso que eu não conheço. Se não são, então, por favor, comente.

Você pode usar a função waitpid no modo não-bloqueio de bloqueio ou para aguardar o sinal de uma determinada criança e, em seguida, fazer algum processamento. Na verdade, você Have usar wait de algum tipo, como é afirmado na resposta de Graham ...

Se você ignorar SIGCHLD em seguida, a tabela de processos vai encher-se com zumbis.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top