Быстрый ответ: родитель сделает что-то, а ребенок сделает что-то еще. Но продолжайте читать ...
Ну, я просто слегка изменил ваш код в этом, и вы получите всю иерархию процессов из результатов вашей программы и ответы на ваш вопрос:
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <unistd.h>
static pid_t my_fork() /* tracing is your friend! :) */
{
pid_t chld = fork();
if (chld > 0) {
/* only the parent shows this */
printf("[pid=%d, child=%d] forked!\n",
getpid(), chld);
}
return chld;
}
int main()
{
/* print our pid, so we know the root of the hierarchy */
printf("[pid=%d] Hello, world\n", getpid());
/* do the embarrasing work */
if (my_fork() && (!my_fork())) {
if (my_fork() || my_fork()) {
my_fork();
}
}
pid_t pid;
int status;
/* We do wait(2)'s while there are children to be waited for.
* it's a good thing to wait for children before ending. */
while((pid = wait(&status)) >= 0) {
printf("[pid=%d, child=%d]: child ended with status=%d\n",
getpid(), pid, status);
}
/* we print the message when no more children are alive */
printf("[pid=%d]: Hello friend!\n", getpid());
return 0;
}
, и это приводит к
$ pru
[pid=72699] Hello, world
[pid=72699, child=72700] forked!
[pid=72699, child=72701] forked!
[pid=72700]: Hello friend!
[pid=72701, child=72702] forked!
[pid=72703]: Hello friend!
[pid=72699, child=72700]: child ended with status=0
[pid=72702, child=72703] forked!
[pid=72702, child=72705] forked!
[pid=72702, child=72703]: child ended with status=0
[pid=72705]: Hello friend!
[pid=72704]: Hello friend!
[pid=72701, child=72704] forked!
[pid=72701, child=72704]: child ended with status=0
[pid=72702, child=72705]: child ended with status=0
[pid=72702]: Hello friend!
[pid=72701, child=72702]: child ended with status=0
[pid=72701]: Hello friend!
[pid=72699, child=72701]: child ended with status=0
[pid=72699]: Hello friend!
, и это иерархия:
[pid=72699] (says Hello, world, just starting)
+-[pid=72700] (created in first fork() call of pid=72699)
`-[pid=72701] (created in second fork() call of pid=72699)
+-[pid=72702] (created in third fork() call of pid=72701)
| +-[pid=72703] (created in fourth fork() call of pid=72702)
| `-[pid=72705] (created in fifth fork() call of pid=72702)
`-[pid=7204] (created in fourth fork() call of pid=72701)
(конечно, иерархия будет другой, если у вас закончатся процессы, и fork(2)
терпит неудачу из-за нехватки системных ресурсов)
Наконец, вы, вероятно, будете беспокоиться о том, почему сообщение
[pid=72703]: Hello friend!
появляется перед сообщением
[pid=72702, child=72703] forked!
но это удивительный мир многозадачности. Сообщение печатается после возврата fork(2)
, поэтому оба сообщения печатаются разными процессами, поэтому их можно запланировать в любом порядке, поэтому ребенок запускает и печатает свое сообщение, прежде чем родитель сможет распечатать, кто его ребенок. Это совершенно нормально.
ПРИМЕЧАНИЕ
Вы должны знать, что fork()
возвращает -1
в случае ошибки, которая в булевом тесте оценивается как true
, так же, как родительский результат. Так что, если вы свободно используете коды возврата из fork(2)
для логических выражений, родитель получит true
или любую ошибку, которая произойдет, если fork()
не получится (ну, они редки, но возможны в загруженной системе) , Просто сохраните код результата fork()
и сначала проверьте на наличие ошибок, а затем вы можете использовать любое логическое выражение, которое вам нужно.
Исходный код выше можно загрузить здесь