首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >进程的系统调用和内存空间

进程的系统调用和内存空间
EN

Stack Overflow用户
提问于 2014-12-15 15:00:48
回答 6查看 16.9K关注 0票数 14

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

但是当我尝试这个程序的时候

代码语言:javascript
复制
#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");
}

其结果是:

代码语言:javascript
复制
*** Parent*****
the address is 0x1370010
   *** Child process  ***
the address is 0x1370010

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

有人能解释一下这里的矛盾吗。请清楚地说明父母和孩子在内存空间中共享的所有内容。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2014-12-15 15:18:53

引用另一条线上自己的话。

  • 当发出叉()系统调用时,创建与父进程对应的所有页面的副本,由操作系统为子进程加载到单独的内存位置。但在某些情况下不需要这样做。考虑当子级执行"exec“系统调用或在fork()之后很快退出时的情况。当只需要子进程为父进程执行命令时,就不需要复制父进程的页面,因为exec用要执行的命令替换了调用它的进程的地址空间。 在这种情况下,使用了一种名为“复制即写(COW)”的技术。使用此技术,当出现分叉时,父进程的页不会被复制到子进程。相反,这些页在子进程和父进程之间共享。每当进程(父进程或子进程)修改页面时,单独为执行修改的进程(父进程或子进程)创建该特定页面的单独副本。然后,此过程将在所有以后的引用中使用新复制的页面,而不是共享的页面。另一个进程(没有修改共享页面的进程)继续使用页面的原始副本(该副本现在不再共享)。这种技术被称为在写上复制,因为当某个进程写入页面时,页面就会被复制.

  • 此外,为了理解为什么这些程序似乎使用相同的内存空间(事实并非如此),我想引用“操作系统:原则和实践”一书的一部分。 大多数现代处理器引入了一种级别的间接,称为虚拟地址。使用虚拟地址,每个进程的内存从“相同”位置开始,例如零。每个过程都认为自己拥有整个机器,尽管在现实中显然并非如此。

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

#包括 int (){ static = 0;printf("%p\n",&a);getchar();返回0;}

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

并通过多次运行该程序得到了如下结果:

票数 36
EN

Stack Overflow用户

发布于 2014-12-15 15:09:44

是的,两个进程对这个变量都使用相同的地址,但是这些地址被不同的进程使用,因此不在同一个virtual address space中。

这意味着地址是相同的,但它们并不指向相同的物理内存。为了理解这一点,您应该阅读更多关于虚拟内存的内容。

票数 13
EN

Stack Overflow用户

发布于 2014-12-15 15:09:29

地址是相同的,但地址空间不是。每个进程都有自己的地址空间,因此父进程的0x1370010与子进程的0x1370010不相同。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27486873

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档