Как правильно fork () n дочерних процессов в C? - PullRequest
12 голосов
/ 05 февраля 2012

Это мой код.

#include <stdio.h>
#include <stdlib.h>

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

for(i = 0; i < atoi(argv[1]); i++) {
    pid = fork();
    if(pid < 0) {
        printf("Error");
        exit(1);
    } else if (pid == 0) {
        printf("Child (%d): %d\n", i + 1, getpid());
        exit(0); 
    } else  {
        wait(NULL);
    }
}

}

Вывод такой.

Child (1): 5676
Child (2): 4624
Child (3): 4800
Child (4): 5596
Child (5): 5580

Однако это не ожидаемый результат в моей домашней работе. Так и должно быть. Что не так с кодом? Кто-нибудь может мне помочь?

Child (2): 4625
Child (1): 4624
Child (3): 4626
Child (4): 4627
Child (5): 4628

Спасибо за вашу помощь. Сейчас попробую.

P.S. Извини я плохо знаю английский. Я надеюсь, вы понимаете, что я сказал.

Ответы [ 4 ]

5 голосов
/ 05 февраля 2012

Ваш код отлично работает на моем компьютере.Это может зависеть от ОС.

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

1 голос
/ 05 февраля 2012

С таким ожидаемым результатом, скорее всего, ваша домашняя работа должна сначала отключить все процессы, а затем вызвать wait.

Просто пропустите ожидающий вызов в цикле и сделайте отдельный вызов, который должен зацикливаться, пока wait не вернет -1 и errno не установится в ECHILD. Обратите внимание, что порядок вывода дочерних элементов будет случайным или, по крайней мере, не полностью, поэтому не обязательно 2 1 3 4 5.

Это только предположение, вы должны предоставить больше информации, если вы хотите более конкретный ответ.

1 голос
/ 05 февраля 2012

Причина, по которой вы получаете неупорядоченный вывод, заключается в том, что вы не можете точно предсказать, какой ребенок станет активным, когда.Таким образом, может случиться так, что выполнение вашего первого ребенка будет отложено до тех пор, пока ваш второй ребенок не будет fork() ed и запущен.

Обычно ваши дети получают последовательные PID, хотя это зависит от ОС.

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

Для уменьшения путаницы вы можете удалить вывод PID в каждой строке.Возможно, они могут быть выведены при соответствующем запуске дочернего процесса, но после этого должно быть достаточно сказать, например, Child 3: straight length 6 <S6,H5,C4,S3,H2,SA> без повторения PID.

1 голос
/ 05 февраля 2012

Система использует бесплатные PID для присвоения процессам. Вы можете разветвляться с идентификатором процесса 4000 и иметь дочерний идентификатор 3900. На вашей домашней работе даже не нужно ставить цифры, потому что первый идентификатор процесса в любом случае никогда не будет прежним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...