#c #loops #fork
#c #циклы #fork
Вопрос:
Я хочу, чтобы основной процесс запускался и создавал 4 подпроцесса. Как только они будут созданы, я хочу, чтобы основной процесс дождался их завершения.
Это весь мой код:
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(){
int i;
int childID;
int status;
for (i=0;i<4;i ){
childID=fork();
if (childID==0){
printf("[%d] I the child, will sleepn", (int)getpid());
sleep(1);
}
}
if (!childID){
wait(amp;status);
printf("[%d] I the parent, have waited for my children!n", (int)getpid());
}
return 0;
}
Вместо этого я получаю следующее:
..
[8508] I the child, will sleep
[8503] I the parent, have waited for my children!
[8511] I the child, will sleep
[8510] I the child, will sleep
[8509] I the child, will sleep
[8520] I the child, will sleep
[8511] I the parent, have waited for my children!
[8510] I the parent, have waited for my children!
(prompt stuck)
Почему родительский файл распечатывается несколько раз, а не один раз, в конце концов?
Комментарии:
1. Ваш вывод не соответствует вашему коду. Исправьте это, пожалуйста
2. В коде, который вы нам дали, нет инструкции, которая печатает «Я, родитель, буду ждать своих детей!». Есть ли что-то еще в коде?
3. Помимо того факта, что ваши дочерние элементы тоже будут разветвляться, как упоминалось в ответах, вы также ждете только последнего разветвленного дочернего элемента, а не всех своих дочерних элементов.
4. Извините за это. Просто я поменял местами позиции wait() и printf в последнюю минуту и забыл также обновить выходные данные.
Ответ №1:
Это не родительский элемент, который записывает несколько раз, а первые 3 дочерних элемента. Когда вы fork
, дочерние элементы получают точную копию процесса, включая его адресное пространство, стек, регистры, все. Это означает, что после первого fork
и родительский, и новый дочерний элемент пройдут for
еще 3 раза, создавая 3 новых дочерних элемента. Вы должны break
выйти из for
при выполнении в качестве дочерних элементов для получения желаемого эффекта:
if (childID==0){
printf("[%d] I the child, will sleepn", (int)getpid());
sleep(1);
break;
}
Комментарии:
1. Я думал, что после запуска fork() будет выполняться только код после его запуска. Так как fork находится внутри цикла, я подумал, что, возможно, он обойдет весь цикл и продолжит после него..
Ответ №2:
Посмотрите на pid отпечатков. 8510 и 8511 являются дочерними элементами, а не исходным родительским элементом. Когда вы разветвляете цикл, дочерние элементы также находятся в этом цикле. Попробуйте поместить a break;
после sleep(1).
Ответ №3:
Когда вы запускаете цикл, после того, как вы разветвляете, дочерний элемент спит во время первой итерации после его разветвления, но затем он разветвляет больше процессов. Поскольку childID
это больше не 0
для этих процессов, не вызывайте wait, и поэтому они не получают своих дочерних элементов. Это означает, что когда все вызовы ожидания будут завершены, у вас все еще будут запущены процессы, поэтому терминал зависнет.