进程虚拟地址空间,进程创建

进程创建

解释一下fork函数

  在Linux中fork函数是很重要的函数,它从已经存在的进程中创建一个新进程,新进程称为子进程,原进程称为父进程。

    #include<unistd.h>

    pid_t fork(void);    返回值:子进程返回0,父进程返回子进程的pid,出错返回-1

进程调用fork,当控制转移到内核中的fork代码后,内核的做法如下:

    1.分配新的内存块和内核数据结构给子进程

    2.将父进程部分数据结构内容拷贝至子进程

    3.添加子进程到系统进程列表中

    4.fork返回,调度器调度

当一个进程调用fork后,就会有两个二进制码相同的进程,而且他们运行到相同的地方,但是每个进程开始自己的旅程

例子:

#include<unistd.h>
#include<stdio.h>
int main()
{
  pid_t pid;
  printf("befor : pid is  %d\n",getpid());
  pid=fork();
   printf("After:pid is %d, fork return %d\n", getpid(), pid);
  sleep(1);
  return 0;
}

运行结果如上,  这里输出了三行,before打印了一行,after打印了两行

由上面的例子可以看出,fork之前父进程独立执行,fork之后,父子进程分别执行

    注意:fork之后谁先执行由调度器决定

fork函数返回值:子进程返回0;父进程返回的是子进程的pid

父子进程代码共享,数据各自开辟空间,私有(写时拷贝)

 

进程虚拟地址空间:

看一段代码

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int g_val=100;
int main()
{
  pid_t id=fork();
  if(id<0)
    {
      perror("fork");
      return 0;
    }
  else if(id==0){
    printf("child[%d]:%d:%p\n",getpid(),g_val,&g_val);}
  else{
    printf("parent[%d]:%d:%p\n",getpid(),g_val,&g_val);}
  sleep(1);
  return 0;
}

    

我们发现输入的变量和地址一样,因为子进程按照父进程为模板,父子并没有对变量进行任何修改

接下来在看一段代码,你可能会迷惑

#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
int g_val=100;
int main()
{
  pid_t id=fork();
  if(id<0)
    {
      perror("fork");
      return 0;
    }
  else if(id==0){
    g_val=200;
    printf("child[%d]:%d:%p\n",getpid(),g_val,&g_val);}
  else{
    sleep(3);
    printf("parent[%d]:%d:%p\n",getpid(),g_val,&g_val);}
  sleep(1);
  return 0;
}

这里在子进程中改变了 g_val的值,按理来说,数据改了,他两的地址不可能一样,因为一块地址上只能放一个数据

但是看一下运行结果:

我们发现父子进程的输出地址是一样的,变量内容不一样,得出以下结论

    1.变量内容不一样,所以父子进程输出的变量绝对不是同一个变量

    2.地址是一样的,说明该地址绝对不是物理地址

    3.在linux中,这种地址叫做虚拟地址

    4.我们在用c、c++语言所看到的地址都是虚拟地址,物理地址用户一概看不到,由OS统一管理

    OS负责将虚拟地址转化为物理地址

创建一个进程时,操作系统会为该进程分配一个4GB大小的虚拟进程地址空间,之所以是4GB,是因为

在32位操作系统中,一个指针长度是4字节,而4字节的寻址能力是从0x00000000--0xFFFFFFFF

而0xFFFFFFFF表示的即为4GB大小的容量

2.每个进程只能访问自己虚拟地址空间的数据,无法访问别的进程中的数据,通过这种方法实现进程间的地址隔离

    

 上面的图足以说明问题,同一个变量,地址相同,其实就是虚拟地址相同,内容不同其实是被映射到

    不同物理地址

注意:1.进程的数据和代码在物理内存上    2.页表的存在是为了保护物理内存

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值