Использование fork () в C - PullRequest
       34

Использование fork () в C

1 голос
/ 19 сентября 2011

Я пишу программу, которая использует процессор для обработки некоторой информации. Программа зависит от ядер процессора. Если имеется 2 ядра, программа дважды выполнит fork (), чтобы создать 2 экземпляра работы и вернуть результаты.

#define CORES 4

void worker(int id)
{    
    // blablabla work here
    printf("worker %d\n",id);
    printf("[%d] I'm child of %d\n",getpid(),getppid());    
}

int main (int argc, const char * argv[])
{
    int pid;

    for (int i=0; i<CORES; i++)
    {
        pid = fork();
        if (pid == 0) // if child
        {
            worker(i);
            exit(0);
        }
        else if (pid>0)
        {
            printf("[%d] Big father here!\n",getpid());
        }
        else
        {
            printf("--- Fork problem ---");
        }
    }

    return 0;

}

Мои вопросы:

  1. Что я могу сделать, чтобы программа завершилась только тогда, когда ВСЕ дочерние процессы завершат обработку необходимой информации? (я думаю, что они становятся сиротами)
  2. Как рассчитать время, прошедшее с начала работы первого процесса до его завершения

Ответы [ 3 ]

6 голосов
/ 19 сентября 2011

Используйте wait(), чтобы дождаться окончания действия детей:

int status;
pid_t pid;

while ((pid = wait(&status)) != -1) {
    // pid just terminated
}

// all children terminated

См. man 2 wait.

Для измерения временисм. gettimeofday():

struct timeval tv = {0};

gettimeofday(&tv, NULL);

struct timeval:

struct timeval {
    time_t      tv_sec;     /* seconds */
    suseconds_t tv_usec;    /* microseconds */
};
3 голосов
/ 19 сентября 2011

Чтобы дождаться завершения дочерних процессов, вы используете любой из системных вызовов wait. Если вы используете wait4, ядро ​​выдаст вам информацию о том, сколько ЦП и время настенного времени потребляет каждый процесс. Однако вы можете обнаружить, что вызов gettimeofday в начале и конце цикла проще.

0 голосов
/ 19 сентября 2011

Один из способов сделать то, что вы хотите: написать обработчик SIGCHLD, который увеличивает счетчик. (Объявите счетчик изменчивым, иначе может произойти неприятность.) Затем sigsuspend () повторно ожидает SIGCHLD. Когда счетчик совпадет с CORES, завершите работу.

Чтобы рассчитать время, вызовите time () непосредственно перед порождением рабочих потоков, а затем непосредственно перед завершением; difftime (3) даст вам разницу во времени в секундах как двойную.

...