Создает ли Fork() в UNIX процессы, которые работают в унисон или последовательно?

При использовании функции fork() в программе, работающей в Unix-подобной операционной системе (например, MINIX 3), она создает ряд отдельных процессов, которые обрабатываются независимо и поэтому могут заканчиваться друг перед другом (что на самом деле хотите) или он создаст серию последовательных процессов, которые завершаются только в том порядке, в котором они были созданы.

Вот код, который я использую для fork()

    for(j = 0; j < num_fork_loops;) {
       if (fork() < 0) {
          printf("Fork has failed\n");
          exit(EXIT_FAILURE);
       }
       j++;
     }

Спасибо за ваше время

5 ответов

Решение

fork() возвращается сразу, дважды. Все процессы нормальные, запущенные процессы, которые планируются отдельно ОС. Как правило, они все будут работать одновременно.

См. Обоснование POSIX для fork особенно этот текст:

Стандарт IEEE Std 1003.1-1988 не требует одновременного выполнения родительского и дочернего элементов fork(). Система, в которой однопоточные процессы явно не предназначены, и считается неприемлемой "игрушечной реализацией" этого тома POSIX.1-2008. Единственное возражение против фразы "выполнять самостоятельно" - это тестируемость, но это утверждение должно быть проверяемым. Такие тесты требуют, чтобы и родитель и потомок могли блокировать обнаруживаемое действие другого, такое как запись в канал или сигнал. Должен быть возможен интерактивный обмен такими действиями, чтобы система соответствовала целям этого тома POSIX.1-2008.

Все исторические реализации fork обеспечили одновременное выполнение, и это всегда было намерением. Это четко прописано в современных версиях стандарта, как

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

Вы должны просто взглянуть на справочную страницу, например. Когда ты fork() созданные процессы идентичны, и вы не знаете, в каком порядке они выполняются.

Смотрите справочную страницу:

fork () создает новый процесс, дублируя вызывающий процесс. Новый процесс, называемый дочерним, является точной копией вызывающего процесса, называемого родительским, за исключением следующих моментов:

Новый процесс выполняется параллельно с родительским процессом, оба продолжают выполнение по возвращении из fork() вызов.

ИМХО твой код правильный:

 Upon successful completion, fork() returns a value of 0 to the child
 process and returns the process ID of the child process to the parent
 process.  Otherwise, a value of -1 is returned to the parent process, no
 child process is created, and the global variable errno is set to indi-
 cate the error.

Но, вероятно, он не делает то, что вы ожидаете, он создает 2^num_fork_loops, если все форки имеют успех. Если форк завершается неудачно, он возвращает -1 и вы правы, чтобы проверить возвращаемое значение, но в случае успеха он возвращает 0 для дочерний и PID (всегда положительный) для отца, поэтому в этом случае также дочерний процесс начнет создавать другие процессы.
Исправьте код, заставив дочерний процесс выполнить что-то еще (если вы не хотите 2^N процессов):

for(j = 0; j < num_fork_loops;j++) {
   pid_t pid=fork();
   if (pid < 0) 
   {
      printf("Fork has failed\n");
      exit(EXIT_FAILURE);
   }
   else if(pid==0)
   {
       j=num_fork_loops; // avoid to continue the loop for the child
       child_routine();
   }
   else
   {
       // This is the father, in case of success of the fork
       j++;
   }
 }
Другие вопросы по тегам