Обновление
Вам не хватает набора скобок в обновленном коде. Это должно быть if ((pid[i] = fork()) == -1)
не if (pid[i] = fork() == -1)
!
Последний эквивалентен if (pid[i] = (fork() == -1))
из-за правил приоритета. В конечном итоге каждый раз в цикле присваивается значение от 0 до pid[i]
, поэтому родители думают, что они являются дочерними процессами, и не выходят из цикла.
Я согласен с вашим анализом того, что должно произойти. Родитель должен породить потомка и затем выйти, поэтому каждая распечатка i=n
должна отображаться только один раз.
Вы уверены, что ввели его точно так, как указано в вашем вопросе? Я запустил вашу программу (с небольшими изменениями) и получил результат, который вы прогнозировали:
$ cat fork.c
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#define N 5
int main() {
int pid[N], i;
for(i=1;i<N;i++) /* What’s the total number of processes? */
{
printf("i=%d\n",i); // Output of all the is
if((pid[i]=fork())==-1) exit(1);
else if(pid[i] > 0) break;
}
return 0;
}
$ gcc -o fork fork.c
$ ./fork
i=1
i=2
$ i=3
i=4
Обратите внимание, что я переместил \n
в распечатке до конца. Когда вы помещаете его в начало строки, в результате stdout
не сбрасывается, поэтому вы получаете несколько распечаток, когда родительский и дочерний процессы сбрасывают свои выходные буферы. Это может быть причиной вашей проблемы. FWIW на моем Mac я получил каждую распечатку дважды.