Как использовать Fork() для создания только 2 дочерних процессов?
Я начинаю изучать C и, изучая форк, ожидаю, что получаю неожиданный вывод. По крайней мере для меня.
Есть ли способ создать только 2 дочерних процесса из родительского?
Вот мой код:
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main ()
{
/* Create the pipe */
int fd [2];
pipe(fd);
pid_t pid;
pid_t pidb;
pid = fork ();
pidb = fork ();
if (pid < 0)
{
printf ("Fork Failed\n");
return -1;
}
else if (pid == 0)
{
//printf("I'm the child\n");
}
else
{
//printf("I'm the parent\n");
}
printf("I'm pid %d\n",getpid());
return 0;
}
И вот мой вывод:
I'm pid 6763
I'm pid 6765
I'm pid 6764
I'm pid 6766
Пожалуйста, не обращайте внимания на часть трубы, я еще не зашел так далеко. Я просто пытаюсь создать только 2 дочерних процесса, поэтому я ожидаю, что 3 "I'm pid ..." выводит только 1 для родительского процесса, который я заставлю ждать, и 2 дочерних процесса, которые будут взаимодействовать через канал.
Дайте мне знать, если увидите, где моя ошибка.
5 ответов
pid = fork (); #1
pidb = fork (); #2
Предположим, что идентификатор родительского процесса равен 100, первая ветвь создает другой процесс 101. Теперь и 100, и 101 продолжают выполнение после # 1, поэтому они выполняют вторую вилку. pid 100 достигает #2, создавая другой процесс 102. pid 101 достигает #2, создавая другой процесс 103. Таким образом, мы получаем 4 процесса.
Что вы должны сделать, это что-то вроде этого.
if(fork()) # parent
if(fork()) #parent
else # child2
else #child1
После создания процесса вы должны проверить возвращаемое значение. если вы этого не сделаете, второй fork()
будет выполняться как родительским процессом, так и дочерним процессом, поэтому у вас есть четыре процесса.
если вы хотите создать 2 дочерних процесса, просто:
if (pid = fork()) {
if (pid = fork()) {
;
}
}
Вы можете создать n дочерних процессов следующим образом:
for (i = 0; i < n; ++i) {
pid = fork();
if (pid > 0) { /* I am the parent, create more children */
continue;
} else if (pid == 0) { /* I am a child, get to work */
break;
} else {
printf("fork error\n");
exit(1);
}
}
Когда оператор fork выполняется родителем, дочерний процесс создается так, как вы ожидаете. Можно сказать, что дочерний процесс также выполняет оператор fork, но возвращает 0, а родитель возвращает pid. Весь код после оператора fork выполняется как родительским, так и дочерним.
В вашем случае произошло то, что первый оператор fork создал дочерний процесс. Так что в настоящее время есть один родитель, P1, и один ребенок, C1.
Теперь и P1, и C1 встречают второй оператор fork. Родитель создает другого дочернего элемента (c2), как и следовало ожидать, но даже дочерний элемент c1 создает дочерний процесс (c3). Таким образом, в действительности у вас есть P1, C1, C2 и C3, поэтому вы получили 4 вывода оператора печати.
Хороший способ думать об этом - использовать деревья, где каждый узел представляет процесс, а корневой узел является верхним родителем.
Вы можете проверить значение, как будто ( pid < 0) создание процесса не удалось, это говорит о том, что создание дочернего процесса было неудачным.. fork возвращает идентификатор процесса дочернего процесса, если getpid() используется из родительского процесса..
Вы можете создать дочерний процесс внутри дочернего процесса. Таким образом, вы можете получить 2 копии исходного родительского процесса.
int main (void) {
pid_t pid, pid2;
int status;
pid = fork();
if (pid == 0) { //child process
pid2 = fork();
int status2;
if (pid2 == 0) { //child of child process
printf("friends!\n");
}
else {
printf("my ");
fflush(stdout);
wait(&status2);
}
}
else { //parent process
printf("Hello ");
fflush(stdout);
wait(&status);
}
return 0;
}
Это печатает следующее:
Hello my friends!