Заставьте детей обрабатывать ожидание до получения сигнала родителя

Я хочу создать N детей от родителя. Я хочу, чтобы все дети начали (функция - измерять время) одновременно. Поэтому я поместил функцию в обработчик сигнала, и когда родительский процесс заканчивает создание (форка) всех дочерних элементов, он отправляет сигнал (используя kill(children_id)) всем дочерним элементам, чтобы позволить стартовать. Код ниже, но он не работает, как ожидалось. В частности, он раздвоил все дочерние элементы, но не выполняет функцию "measure_time" вообще. Эта функция не записывает время выполнения и распечатывает. Может ли кто-нибудь дать мне знать, если я делаю что-то не так?

    int n_task = 4;
    for (i = 0; i < n_task; i++){
            pid = fork();
            if (pid < 0){
                    printf("cannot fork!\n");
            } else
            if (pid == 0){ //child
                    printf("printed from child [%d]\n", getpid());                        
                    signal(SIGUSR1, measure_time); //measure_time is a function
                    exit(0);
            } else {
                    pid_array[i] = pid;
            }
    }

    //This code is executed from parent only
    for (int i = 0; i < n_task; i++)
    {
            kill(pid_array[i], SIGUSR1);                
    }

2 ответа

Решение
if (pid == 0){ //child
    printf("printed from child [%d]\n", getpid());                        
    signal(SIGUSR1, measure_time); //measure_time is a function
    exit(0);
}

Дети создаются, настраивают обработчик и немедленно выходят (т.е. умирают). Заставьте их спать или заблокируйте что-нибудь, чтобы у родителей было время доставить сигналы.

Обновить

#define _POSIX_SOURCE

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

void measure_time(int sig)
{
    printf("child [%d] received signal %d\n", getpid(), sig);
}

int main(int argc, char *argv[])
{
    int n_task = 4;

    pid_t pid;
    pid_t pid_array[n_task];

    for (int i = 0; i < n_task; i++)
    {
        pid = fork();

        if (pid < 0)
        {
            perror("fork");
            exit(1);
        }

        if (pid == 0) //child
        {
            printf("printed from child [%d]\n", getpid());
            signal(SIGUSR1, measure_time); //measure_time is a function
            sleep(5);

            exit(0);
        }

        //parent
         pid_array[i] = pid;
    }    

    //This code is executed from parent only
    sleep(1);

    for (int i = 0; i < n_task; i++)
        kill(pid_array[i], SIGUSR1);

    for (int i = 0; i < n_task; i++)
        wait(NULL);    

    return (0);
}

Все процессы и потоки подчиняются капризам планировщика ОС. В вашем исходном коде дочерние элементы и родительские элементы могут потенциально завершиться до того, как произойдет последовательность событий, которые вы надеетесь осуществить. Дети могут умереть до того, как родитель отправит сигнал; родитель может послать свои сигналы прежде, чем дети когда-либо установят свой обработчик (и SIGUSR1 завершит процесс, потому что это по умолчанию в отсутствие обработчика). Так мало кода для выполнения всего этого происходит за миллисекунды, меньше, чем время, запланированное для запуска любого из этих процессов (и, следовательно, настройки, достаточной для выполнения ваших ожиданий). Я добавил несколько sleep дать ему немного передышки и wait поэтому родитель не умирает. Это должно позволить вам увидеть, как это работает.

if (pid == 0){ //child
    printf("printed from child [%d]\n", getpid());                        
    signal(SIGUSR1, measure_time); //measure_time is a function
    pause();
    exit(0);
}

Я думаю, проблема в том, что дочерние процессы завершаются сразу после их создания. так
Используйте функцию pause() для ожидания поступления сигнала.

И если некоторые дочерние процессы не будут отвечать должным образом, попробуйте также.

for (j = 0; j < n_task; j++)
    {
            kill(pid_array[j], SIGUSR1); 
            sleep(1);
    }
Другие вопросы по тегам