Почему я не могу поймать SIGCHLD каждый раз после разветвления? - PullRequest
0 голосов
/ 20 апреля 2020

Я пытаюсь создать 4 дочерних процесса, и пока дочерние элементы не будут ждать родительский процесс ie. Я написал программу, но когда я запускаю этот код, 1 из 10, он не может поймать SIGCHLD от каждого дочернего элемента, и моя программа достигает бесконечного l oop после. Это случается очень редко, но все же ..

Не могли бы вы сказать, почему и как я могу это исправить?

Вот мой код.

sig_atomic_t child_exit_status;
sig_atomic_t child_numbers = 0;

void clean_up(int signal_number, siginfo_t * info, void* context)
{
    //printf("SIGCHILD from %d calling\n", info->si_pid);
    waitpid(info->si_pid, &child_exit_status, 0);
    child_numbers++;
}


int main(int argc, char **argv)
{
    // SIGCHLD catcher 
    struct sigaction sigchld_action;
    memset(&sigchld_action, 0, sizeof(sigchld_action));
    sigchld_action.sa_sigaction = &clean_up;
    sigchld_action.sa_flags = SA_SIGINFO;
    sigaction(SIGCHLD, &sigchld_action, NULL);


    int pid1, pid2, pid3, pid4;


    printf("pid : %d\n", getpid());

    pid1 = fork();
    //child1
    if(pid1 == 0)
    {
        printf("child1 %d, parent %d\n", getpid(), getppid());
    }
    else
    {
        pid2 = fork();
        //child2
        if(pid2 == 0)
        {
            printf("child2 %d, parent %d\n", getpid(), getppid());
        }
        else
        {
            pid3 = fork();
            //child3
            if(pid3 == 0)
            {
                printf("child3 %d, parent %d\n", getpid(), getppid());
            }
            else
            {
                pid4 = fork();
                //child4
                if(pid4 == 0)
                {
                    printf("child4 %d, parent %d\n", getpid(), getppid());
                }
                else
                {
                    while(child_numbers < 4)
                    {

                    }
                    printf("i got the signals.");
                }

            }

        }

    }



    return 0;
}

Я пробовал что-то новое, но оно также не работает ..

void clean_up(int signal_number, siginfo_t * info, void* context)
{
    printf("SIGCHILD from %d calling\n", info->si_pid);
    while (1)
    {
        int status;
        pid_t pid = waitpid(-1, &status, WNOHANG);
        if (pid <= 0) 
        {
            break;
        }
        else
        {
            waitpid(pid, &status, 0);
            break;
        }
    }
    child_numbers++;
}

...