c - fork()系统调用和进程的内存空间

标签 c operating-system fork

我引用“当一个进程使用 fork() 调用创建一个新进程时,只有共享内存段在父进程和新 fork 的子进程之间共享。堆栈和堆的副本是为新创建的创建的Silberschatz 的“操作系统概念”解决方案。

但是当我试用这个程序时

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

#define   MAX_COUNT  200

void  ChildProcess(void);                /* child process prototype  */
void  ParentProcess(void);               /* parent process prototype */

void  main(void)
{
         pid_t  pid;
         char * x=(char *)malloc(10);

         pid = fork();
         if (pid == 0) 
            ChildProcess();
         else 
            ParentProcess();
        printf("the address is %p\n",x);
}

void  ChildProcess(void)
{
          printf("   *** Child process  ***\n");
}

void  ParentProcess(void)
{
         printf("*** Parent*****\n");
}

结果是这样的:

*** Parent*****
the address is 0x1370010
   *** Child process  ***
the address is 0x1370010

父子都在堆中打印相同的地址。

谁能给我解释一下这里的矛盾。请清楚说明内存空间中父子共享的所有东西是什么。

最佳答案

从另一个线程引用我自己。

  • When a fork() system call is issued, a copy of all the pages corresponding to the parent process is created, loaded into a separate memory location by the OS for the child process. But this is not needed in certain cases. Consider the case when a child executes an "exec" system call or exits very soon after the fork(). When the child is needed just to execute a command for the parent process, there is no need for copying the parent process' pages, since exec replaces the address space of the process which invoked it with the command to be executed.

    In such cases, a technique called copy-on-write (COW) is used. With this technique, when a fork occurs, the parent process's pages are not copied for the child process. Instead, the pages are shared between the child and the parent process. Whenever a process (parent or child) modifies a page, a separate copy of that particular page alone is made for that process (parent or child) which performed the modification. This process will then use the newly copied page rather than the shared one in all future references. The other process (the one which did not modify the shared page) continues to use the original copy of the page (which is now no longer shared). This technique is called copy-on-write since the page is copied when some process writes to it.

  • 此外,为了理解为什么这些程序似乎使用相同的内存空间(事实并非如此),我想引用《操作系统:原理与实践》一书的一部分。

    Most modern processors introduce a level of indirection, called virtual addresses. With virtual addresses, every process's memory starts at the "same" place, e.g., zero. Each process thinks that it has the entire machine to itself, although obviously that is not the case in reality.

    所以这些虚拟地址是物理地址的翻译,并不代表相同的物理内存空间,举一个更实际的例子我们可以做一个测试,如果我们多次编译运行一个显示方向的程序静态变量,比如这个程序。

    #include <stdio.h>
    
    int main() {
        static int a = 0;
    
        printf("%p\n", &a);
    
        getchar();
    
        return 0;
    }
    

    不可能在两个中获得相同的内存地址 如果我们直接处理物理内存,则不同的程序。

    并且多次运行程序得到的结果是……

enter image description here

关于c - fork()系统调用和进程的内存空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27486873/

相关文章:

windows - 我的 Delphi 7 应用程序在 Application.Initialize 上停止并且不返回到下一行

c - pipeline() 将结构从子级发送到父级。 read() 中的象形文字;

c - 从当前时间减去 1 小时(奇怪的行为)

Python 2.7,操作系统检测返回值

c - 为什么不允许多次定义 C 结构体的成员?

c++ - 如何找到操作系统的名称?

linux - 如何在 Linux 内核中创建新进程?

c - 在 fork() 之后寻求关于 'file descriptor' 的简单描述

c - 如何检测互斥条件

c - 数组元素之前的取消引用运算符?