Создает ли 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++;
}
}