Страницы

Поиск по вопросам

четверг, 12 декабря 2019 г.

Как работает функция fork() в C. Не могу понять результат работы программы

#c #процесс


У меня есть вот такой короткий пример кода, нам его дали что бы продемонстрировать
работу функции fork():

#include 
#include 
#include 
#include 
int main () {

pid_t pid;
pid = fork();
pid = fork();

printf("Fork-Test\n");

return EXIT_SUCCESS;
}


Мне не совсем понятен результат.
В итоге у меня 4 раза в терминале пишет Fork-Test
Не понимаю, во-первых почему это происходит больше одного раза, ведь я вызваю метод
printf("Fork-Test\n"); только один раз, во-вторых, раз уже несколько раз, то почему
именно 4? При чем еще и в следующем виде:

Fork-Test
Fork-Test

Process returned 0 (0x0) execution time : 0.007 s
Press ENTER to continue 
Fork-Test
Fork-Test


смысл мне не понятен.
буду благодарна за любые пояснения по поводу fork()
    


Ответы

Ответ 1



Процесс после системного вызова fork, раздваивается, у исходного процесса создаётся идентичный потомок-двойник в идентичном состоянии (ну почти). Создавшийся процесс будет занят выполнением того же кода ровно с той же точки, что и исходный процесс. Различить кто создал, а кто создался, можно по возвращаемому значению fork, поэтому его результат обычно передаётся в if, чтобы эти процессы выполнили какие-то разные вещи, один пошёл в ветку if, другой в ветку else. Вы же возвращаемое значение игнорируете (сохраняете, но никак не используете), и потому оба процесса продолжают идти по одному и тому же пути. И натыкаются на ещё один вызов fork. И каждый из них раздваивается снова. Получается следующая картина: P # перед первым pid = fork(); [fork 1] P # перед вторым pid = fork(); \ P(1) # перед вторым pid = fork(); [fork 2] P # перед printf("Fork-Test\n"); / \ P(2) P(1) # перед printf("Fork-Test\n"); # перед printf("Fork-Test\n"); \ P(1)(2) # перед printf("Fork-Test\n"); После второго форка процессов уже 4. И после этих форков каждый процесс доходит до вызова printf и выводит указанную строку. Каждый процесс делает это сам. Поэтому вывод происходит столько раз, сколько вышло процессов. Можете убедиться в этом, поместив вывод перед вторым форком (вывод произойдёт дважды) или перед первым (единожды). Завершаются они независимо друг от друга. У вас получилось, что процесс P завершился вторым. А нечто, через что вы запускали этот процесс, следило только за процессом P, но не его "клонами" (т. к. у них собственные pid, process ID), поэтому для остальных такого вывода нет.

Ответ 2



Трудность понимания fork состоит в том, что все запускаемые процессы имеют дело с одним и тем же вами написанным кодом. Когда вы вызвали fork первый раз #include #include #include #include int main () { pid_t pid; pid = fork(); // после первого вызова fork pid = fork(); printf("Fork-Test\n"); return EXIT_SUCCESS; } То та часть вашей программы, которая расположена после комментария, выполняется уже двумя процессами. Правда, каждый из процессов имеет свое адресное пространство. Вы можете представить это следующим образом Родительский процесс Дочерний процесс ==================== ================ pid = fork(); pid = fork(); printf("Fork-Test\n"); printf("Fork-Test\n"); return EXIT_SUCCESS; return EXIT_SUCCESS; } } Теперь каждый из процессов встречает на своем пути следующий вызов fork. Поэтому появляется еще два процесса. И все четыре процесса выполняют каждый в своем адресном пространстве предложения printf("Fork-Test\n"); return EXIT_SUCCESS; } В документации в описании fork написано fork() creates a new process by duplicating the calling process. The new process is referred to as the child process. The calling process is referred to as the parent process. The child process and the parent process run in separate memory spaces. **At the time of fork() both memory spaces have the same content.** Обратите внимание на последнее предложение из цитаты. Это означают, что каждый процесс имеет, грубо говоря, тот же самый исходный код вашей программы, выполнение которого для нового процесса начинается после предложения с вызовом fork .

Комментариев нет:

Отправить комментарий