2014-01-04 4 views
1

У меня есть программа C с вызовом fork().Как работает fork() в gcc-компиляторе?

#include <stdio.h> 
#include <unistd.h> 

main () 
{ 
    fork() ; 
    printf ("\nHello") ; 
    fork() ; 
    printf ("\nWorld") ; 
} 

Это выход я на НКУ:

Hello Hello World World World World 

Если это не будет:

Hello Hello World World Hello Hello World World 

Из-за следующего:

Line1: First fork creates a child process. 
1.2: Prints 'Hello' 
1.3:Creates a child process because of 2nd fork in it. 
1.3.2:Prints 'Hello' and 'World'. 
1.4:Prints 'World'. 
Line2: Prints 'Hello'. 
Line3: Second fork() creates child process 
3.1:creates a child process 
3.2: Prints 'Hello' 
3.4: Prints 'World' 
Line 4: Prints 'World' 

Это как я думаю, эта программа будет работать. Не могли бы вы объяснить, где я ошибся. Вот почему я хочу понять, как работает эта функция.

Примечание. Я проверил страницу руководства, но я не очень понимаю ее.

Также номера являются номерами строк основной функции. Пример: 1.2 соответствует второй строке дочернего процесса, созданного вызовом fork() линии 1 основного() и т. Д.

Я не могу понять, как он производит этот конкретный результат. Итак, я хочу понять, что происходит во время fork(), вызывается простыми шагами?

+1

Кстати, добавьте 'fflush (стандартный вывод)' после каждого 'printf', или выход может стать более сложным для понимания из-за буферизации библиотеки C. –

ответ

10

Итак:

не
  1. Там нет твердой гарантии, которые заказывали вещи будут происходить в (что все зависит от планировщика), кроме первой вещи, безусловно, будет «Hello» и последнее, что, безусловно, быть «миром».
  2. К тому времени, когда вы дойдете до строки «Привет», будут две копии программы (одна вилка плюс оригинал), поэтому «Привет» будет печатать дважды. Каждая из этих копий разворачивает другую копию, поэтому к тому времени, когда вы доберетесь до «Мира», будет четыре копии, поэтому «Мир» будет печатать четыре раза.
  3. Когда вы используете fork(), оно начинается прямо здесь; он не начинается с самого начала.
+0

Но я всегда получаю тот же результат. И если вилка создает копию, которая начинается прямо там, тогда должен быть выход: Hello World World Hello World World ??? – BharathYes

+1

@BharathYes Я не удивлен; система, вероятно, собирается планировать одни и те же события в одном и том же порядке каждый раз (т. е. каждый запуск программы делает то же самое, поэтому он, вероятно, каждый раз назначается так же). Было бы действительно действительно удивительно, если бы один поток зашел слишком далеко впереди других (fork занимает некоторое время, по сравнению с printf), но теоретически один процесс может завершиться до того, как кто-то напечатает что-нибудь. – tabstop

+1

Итак, вы говорите, что, поскольку потоки выполняются параллельно друг другу, они печатают «Hello» и «World» с небольшой разницей во времени. Я понимаю это сейчас. Спасибо за объяснение с терпением. – BharathYes

3

Когда вы используете fork() для ребенка, оно начинается прямо со следующей строки кода, и оно не начинается с начала.

основной():

Line1 Creates child one 
Line2 prints "Hello" 
Line3 Creates child two 
Line4 prints "World" 

ребенок один:

Line2 prints "Hello" 
Line3 Creates child three 
Line4 prints "World" 

ребенок два:

Line4 prints "World" 

ребенок три:

Line4 prints "World" 

Таким образом, один из возможных ответов

Hello Hello World World World World 

от основных, ребенок один, главный, ребенок один, ребенок два и ребенок три соответственно

Однако порядок выполнения может измениться (Race Condition)

1

Вы не можете быть уверены, какой процесс будет выполняться первым, когда будет сделан вызов fork. Следовательно, нет никакого способа узнать правильный порядок выхода.

Единственная гарантия заключается в том, что будет выполняться все процессы, раздвоенные дочерние и родительские.

Теперь после первой вилки есть два процесса, поэтому вы можете быть уверены, что по крайней мере два Hello и два World будут напечатаны. Хотя, после печати двух Hello, есть еще одна вилка.

Теперь эта вилка будет выполнена обоими процессами и, следовательно, теперь у вас будет возможность для процессов в состоянии готовности, и каждый из них будет печатать World. Следовательно, именно поэтому вы видите, в конечном выходе дваHello и четыреWorld

Смежные вопросы