父子进程虚拟地址空间情况

这篇博客介绍了Linux中fork创建的父子进程如何共享内存空间,特别是通过写时拷贝(copy-on-write)机制来实现资源的高效利用。在fork后,父子进程共享相同的虚拟地址空间,但实际物理地址在写操作时才会复制。同时,文件描述符在父子进程间是共享的,导致它们对同一文件的操作会相互影响。通过一个示例程序展示了即使父子进程中的变量地址相同,但在写操作时会触发页表的复制,确保数据的独立性。
摘要由CSDN通过智能技术生成

父子进程虚拟地址空间情况

笔记来源于牛客网《Linux多进程开发》

在这里插入图片描述
在这里插入图片描述

The child process and the parent process run in separate memory spaces. At the time of fork() both memory spaces have the same content. Memory writes, file mappings (mmap(2)), and unmappings (munmap(2)) performed by one of the processes do not affect the other.

实际上,更准确来说,Linux的fork使用是通过写时拷贝(copy-on-write)实现。写时拷贝是一种推迟甚至避免拷贝数据的技术。内核此时并不复制整个进程的地址空间,而是让父子进程共享同一个地址空间。只用在需要写入的时候才会复制地址空间,从而使各个进程拥有各自的地址空间。也就是说,资源的复制是在需要写入的时候才会进行,在此之前,只有以只读方式共享。
注意:fork之后父子进程共享文件,fork产生的子进程与父进程相同的文件描述符指向相同的文件表,引用计数增加,共享文件偏移指针。

这里粘贴一个非常有意思的例子



	
	
		#include <stdio.h>
	

	
		#include <sys/types.h>
	

	
		#include <unistd.h>
	

int main(){
    //为什么进程中的num地址是一样的呢?
    int num = 10;
    printf("original num: %d\n", num);
    //输出原地址
    printf("Address of original num: %p\n", &num); 
    pid_t pid = fork();
    
    if (pid > 0){
        printf("Parent process, PID = %d\n", getpid());
        num += 1;
        printf("num+1 in parent process: %d\n", num);
        //输出父进程中num的地址
        printf("Address of num in parent precess: %p\n", &num);
    }
    
    if (pid == 0){
        printf("Child process, PID = %d\n", getpid());
        num += 2;
        printf("num+2 in child process: %d\n", num);
        //输出子进程中num的地址
        printf("Address of num in child precess: %p\n", &num);
    }
    return 0;
}

结果:
输出结果中父子进程地址一样,为什么呢?
original num: 10
Address of original num: 0x7fffffffe200
Child process, PID = 5498
num+2 in child process: 12
Address of num in child precess: 0x7fffffffe200
Parent process, PID = 5493
num+1 in parent process: 11
Address of num in parent precess: 0x7fffffffe200

解释:
不同的进程访问同样的逻辑地址(虚拟地址)而对应的物理地址不同,是由于各自页表的不同。上面打印出来的所有address都是虚拟地址
linux系统下每个进程都拥有自己的页表,父进程fork出新的子进程时,子进程拷贝一份父进程的页表,且父子进程将页表状态修改为写保护。当父进程或子进程发生写操作时将会发生缺页异常,缺页异常处理函数将会为子进程分配新的物理地址。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值