简体   繁体   English

令人困惑的叉系统调用

[英]confusing fork system call

i was just checking the behaviour of fork system call and i found it very confusing. 我只是检查fork系统调用的行为,我发现它非常混乱。 i saw in a website that 我在一个网站上看到了

Unix will make an exact copy of the parent's address space and give it to the child. Unix将精确复制父级的地址空间并将其提供给孩子。 Therefore, the parent and child processes have separate address spaces 因此,父进程和子进程具有单独的地址空间

#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);
}
}

the output of the above program is : 上述程序的输出是:

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

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

so from the above mentioned statement it seems that child and parent have separet address spaces.this is the reason why char value is printed separately and why am i seeing the address of the variable as same in both child and parent processes.? 所以从上面提到的陈述看来,孩子和父母似乎有separet地址空间。这就是为什么char值被单独打印的原因以及为什么我在子进程和父进程中看到变量的地址相同。

Please help me understand this! 请帮我理解这个!

Basically the concept of virtual memory gives a view to the process as if it is the sole owner of the system. 基本上,虚拟内存的概念提供了一个过程视图,就好像它是系统的唯一所有者一样。 It feels it has access to the complete memory. 它感觉它可以访问完整的内存。

But in reality, the OS gives it only a virtual memory which is mapped to the actual memory by the OS by using MMU. 但实际上,操作系统只给它一个虚拟内存,操作系统使用MMU映射到实际内存。

So, what happens in your case is, each process (parent and child) have their own address space. 那么,在你的情况下发生的是,每个进程(父进程和子进程)都有自己的地址空间。 And this is separate for both. 这对两者都是分开的。 Now here, the address space refers to the virtual address space. 现在,地址空间指的是虚拟地址空间。

So, though both in parent and child the same address is present, this is just the virtual address. 因此,虽然在父级和子级中都存在相同的地址,但这只是虚拟地址。 and each maps to a different physical address. 并且每个映射到不同的物理地址。

Hope it helps!! 希望能帮助到你!!

You're right. 你是对的。 As soon as you call fork() , two identical processes exist. 一旦调用fork() ,就会存在两个相同的进程。 Therefore, the address of y is the same for the copy of y in each process. 因此, y的地址对于每个进程中的y副本是相同的。 The only difference between the two processes is that in one, fork() returned 0 , and in the other it returned the PID of the child. 两个进程之间的唯一区别是,在一个中, fork()返回0 ,而在另一个中它返回子进程的PID。 Your program is using that information to do different behaviour in the parent and child, so you get the appropriate output. 您的程序正在使用该信息在父级和子级中执行不同的操作,因此您可以获得适当的输出。

In "real life", operating systems do a lot of optimizations to make fork() really fast. 在“现实生活”中,操作系统进行了大量优化,使fork() 非常快。 That means that the actual physical behaviour probably doesn't involve a complete copy of the memory space. 这意味着实际的物理行为可能不涉及内存空间的完整副本。 Logically, however, you can treat it as such. 但是,从逻辑上讲,您可以这样对待它。

They have separate address space -- that is precisely why the same memory address is allowed to have different values. 它们具有单独的地址空间 - 这正是为什么允许相同的存储器地址具有不同的值。 A memory address only has meaning in the context of a process. 内存地址仅在进程的上下文中有意义。

Address 221 P Street is a separate building from address 221 C Street. 地址221 P Street是一个独立的建筑,地址为221 C Street。 Their contents differ even though they have the same address number. 即使它们具有相同的地址编号,它们的内容也不同。

You have to replace pid with ptr . 你必须用ptr替换pid To get the parent and child ID you must use pid in printf(" Address is %p\\n",pid); 要获取父ID和子ID,必须在printf(" Address is %p\\n",pid);使用pid printf(" Address is %p\\n",pid); instead of ptr . 而不是ptr After fork() program runs in two parts. fork()程序运行后分为两部分。 One is child and the other one is parent. 一个是孩子,另一个是父母。 If you call for address from a variable that used before fork() ,you will get the same result both for parent and child. 如果从fork()之前使用的变量调用地址,您将获得父和子的相同结果。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM