запутанный системный вызов fork - PullRequest
4 голосов
/ 25 марта 2010

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

Unix сделает точную копию адресного пространства родителя и передаст ее ребенку. Поэтому родительский и дочерний процессы имеют отдельные адресные пространства

#include <stdio.h>
#include <sys/types.h>

int main(void)
{
pid_t pid;
char y='Y';
char *ptr;
ptr=&y;
pid = fork();
if (pid == 0)
{
y='Z';
printf(" *** Child process  ***\n");
printf(" Address  is %p\n",ptr);
printf(" char value is %c\n",y);
sleep(5);
}
else
{
sleep(5);
printf("\n ***parent process ***\n",&y);
printf(" Address  is %p\n",ptr);
printf(" char value is %c\n",y);
}
}

вывод вышеуказанной программы:

 *** Child process  ***
 Address  is 69002894
 char value is Z

 ***parent process ***
 Address  is 69002894
 char value is Y

Таким образом, из вышеприведенного утверждения кажется, что дочерний и родительский элементы имеют адресные пространства с разделением. Это причина, по которой значение char печатается отдельно и почему я вижу, что адрес переменной одинаков как в дочерних, так и в родительских процессах.?

Пожалуйста, помогите мне понять это!

Ответы [ 5 ]

7 голосов
/ 25 марта 2010

В основном концепция виртуальной памяти дает представление о процессе, как будто он является единственным владельцем системы. Он чувствует, что имеет доступ к полной памяти.

Но в действительности ОС предоставляет ей только виртуальную память, которая сопоставляется фактической памяти с помощью MMU.

Итак, в вашем случае каждый процесс (родительский и дочерний) имеет свое собственное адресное пространство. И это отдельно для обоих. Теперь здесь адресное пространство относится к виртуальному адресному пространству.

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

Надеюсь, это поможет !!

6 голосов
/ 25 марта 2010

Они имеют отдельное адресное пространство - именно поэтому один и тот же адрес памяти может иметь разные значения. Адрес памяти имеет значение только в контексте процесса.

6 голосов
/ 25 марта 2010

Ты прав. Как только вы вызываете fork(), существуют два идентичных процесса. Следовательно, адрес y одинаков для копии y в каждом процессе. Единственное различие между этими двумя процессами состоит в том, что в одном fork() возвращено 0, а в другом - PID дочернего процесса. Ваша программа использует эту информацию для различного поведения родительского и дочернего элементов, поэтому вы получите соответствующий вывод.

В «реальной жизни» операционные системы проводят множество оптимизаций, чтобы сделать fork() действительно быстрым. Это означает, что фактическое физическое поведение, вероятно, не включает в себя полную копию пространства памяти. Однако, по логике вещей, вы можете относиться к нему как таковому.

3 голосов
/ 25 марта 2010

Адрес 221 P Street является отдельным зданием от адреса 221 C Street. Их содержимое отличается, даже если у них одинаковый номер адреса.

1 голос
/ 16 марта 2013

Вы должны заменить pid на ptr. Чтобы получить идентификатор родителя и ребенка, вы должны использовать pid в printf(" Address is %p\n",pid); вместо ptr. После fork() программа запускается в две части. Один ребенок, а другой родитель. Если вы вызываете адрес из переменной, которая использовалась до fork(), вы получите одинаковый результат как для родителя, так и для ребенка.

...