Ответ 1
Это может помочь понять, почему слово вилка использовалось для обозначения этой функции. Вы когда-нибудь слышали о "вилке на дороге"? На развилке процесс должен разделить пути.
Сначала выполняется один процесс, выполняющийся нормально, пока вы не достигнете вызова fork
. Когда вызывается fork, создается новый процесс, который практически полностью идентичен исходному процессу , за исключением возвращаемого значения функции fork. Созданный процесс называется дочерним процессом, и, следовательно, процесс, породивший его, называется родительским процессом.
Поскольку вы хотите выполнять разные задачи для каждой ветки fork, это требует, чтобы вы могли отличить дочерний процесс от родительского процесса. То, где возвращается возвращаемое значение fork
: fork
возвращает идентификатор процесса (pid) дочернего элемента (вновь созданного процесса) родительскому; он возвращает 0 дочернему элементу. Кроме того, если выполнение fork
идет не так, возвращаемое значение равно -1.
В вашем коде вы не различаете дочерний и родительский процессы, поэтому оба процесса запускают весь код, следующий за вызовом fork
.
//what the child process looks like after fork is called
int main()
{
int a, b;
b=fork(); // <-- current line of execution: 0 is returned to b
printf("\nmy name is manish\n");
printf("\n my name is anil\n");
printf("\n the value of b = %d",b);
}
// what the parent process looks like after fork is called
int main()
{
int a, b;
b=fork(); // <-- current line: child process id is returned
printf("\nmy name is manish\n");
printf("\n my name is anil\n");
printf("\n the value of b = %d",b);
}
Как вы можете видеть, оба процесса имеют один и тот же код, следующий за fork, поэтому вывод повторяется. Возможно, если вы хотите, чтобы родительский процесс выводил Manish и child для вывода Anil, вы можете сделать что-то вроде:
int main()
{
pid_t b; // note that the actual return type of fork is
// pid_t, though it probably just an int typedef'd or macro'd
b = fork();
if (b == -1) perror("Fork failed");
else if (b > 0) {
printf("My name is Manish\n"); // parent process
else
printf("My name is Anil\n"); // child process
printf("The value of b is %d\n", b);
return 0;
}
Наконец, последний комментарий, который должен быть сделан, заключается в том, что в вашем коде вывод, кажется, был выполнен сначала одним процессом целиком, а затем другим процессом в целом. Это не всегда так. Например, операционная система может позволить родительскому процессу выполнить вывод "manish", а затем заставить этот процесс ждать и передать процессор процессу дочернего процесса, который затем выполняет "manish". Тем не менее, дочерний процесс может продолжаться и выполнять "anil" и "b" выходы, завершая выполнение дочернего процесса и тем самым возвращая выполнение обратно в родительский процесс. Теперь родитель заканчивает выполнение, выведя "anil" и "b". Конечный результат запуска этой программы может выглядеть примерно так:
my name is manish // executed by parent my name is anil // child the value of b = 0 // child my name is anil // parent the value of b = 2244 // parent [email protected]:~$
Взгляните на страницу руководства fork
.
Также посмотрите waitpid
для правильной обработки дочерних процессов родительскими процессами, чтобы вы не создавали зомби.
Изменить. Отвечая на ваши вопросы в комментариях, я отвечу, как вы можете просто последовательно запускать каждый процесс.
int main()
{
pid_t pid;
int i;
for (i=0; i<NUM_PROCESSES; i++)
{
pid = fork();
if (pid == -1)
{
perror("Error forking");
return -1;
}
else if (pid > 0)
{
// parent process
waitpid(-1, NULL, 0); //might want to look at man page for this
// it will wait until the child process is done
}
else
{
// do whatever each process needs to do;
// then exit()
doProcess(i);
exit(0);
}
}
// do anything else the parent process needs to do
return 0;
}
Конечно, это не лучший код, а просто для иллюстрации. Большая идея здесь - вызов waitpid
, который заставляет родительский процесс ждать, пока дочерний процесс не обработает его просто fork
ed, чтобы завершить работу. После завершения дочернего prcoess родитель продолжается после вызова waitpid
, начиная новую итерацию цикла for
и разворачивая другой (следующий) процесс. Это продолжается до тех пор, пока весь дочерний процесс не будет выполнен последовательно, и выполнение окончательно вернется к родительскому.