父子进程的虚拟空间

        在 fork() 调用之后,父进程和子进程会共享相同的代码和数据段,但是它们会有各自独立的虚拟空间,尤其是在数据段的部分。以下是一些关于父子进程虚拟空间的重要说明:

  1. 代码和只读数据:

    • 父子进程共享相同的代码和只读数据。这些部分在内存中是相同的,而不会被修改。
  2. 数据段(Data Segment):

    • 父子进程有各自独立的数据段。任何一个进程对其数据段的修改都不会影响另一个进程的数据段。
  3. 堆(Heap):

    • 堆是动态分配内存的区域,通过 malloccalloc 等函数进行分配。在 fork() 之后,父子进程都有各自独立的堆。在一个进程中释放堆中的内存不会影响另一个进程。
  4. 栈(Stack):

    • 栈是用于函数调用和局部变量存储的区域。在 fork() 之后,父子进程有各自独立的栈。栈上的变化不会影响另一个进程。
  5. 文件描述符表:

    • 父子进程共享相同的文件描述符表。当父子进程中一个进程关闭了一个文件描述符时,不会影响另一个进程。
  6. 内存映射和共享内存:

    • fork() 之后,任何通过 mmap 创建的内存映射都会在父子进程之间共享,这可能会导致需要额外的同步。

总体来说,虽然父子进程共享一些内存区域,但是它们各自有独立的虚拟地址空间,使得彼此的操作不会相互干扰。这是通过使用虚拟内存机制来实现的,每个进程都有自己的虚拟地址空间,这个虚拟地址空间与物理内存的映射由操作系统负责管理。

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

父子进程内核中的pid是不一样的。 

"读时共享,写时拷贝" 是指在 fork() 时,父子进程共享相同的内存页,但是只有在其中一个进程尝试写入该页时,才会发生拷贝操作。这个机制是为了提高效率,避免不必要的内存复制。

具体来说:

  1. 读时共享(Read-Shared):

    • fork() 时,父子进程共享相同的物理内存页。
    • 如果父进程或子进程中的任意一个进程尝试读取这个共享页,那么它们都会看到相同的内容。
    • 这样的共享使得父子进程在开始时能够共享相同的状态。
  2. 写时拷贝(Copy-On-Write):

    • 如果父子进程中的任何一个尝试对共享的内存页进行写操作,操作系统就会触发一个拷贝操作。
    • 拷贝操作会创建一个新的物理内存页,然后将写入的数据复制到新页上,使得修改只影响修改的那个进程,而不影响其他进程。
    • 这样可以确保父子进程之间的写操作互不影响,每个进程都有自己的一份私有拷贝。

这种机制的优势在于在 fork() 之后,如果父子进程中的一个进程只是读取共享的数据而不修改,那么它们可以共享相同的物理内存,而无需进行实际的拷贝操作,从而提高了效率。只有在有写操作时才会发生实际的拷贝,确保了数据的一致性和独立性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值