LINUX进程变量隔离 虚拟地址

01 虚拟地址

Linux系统中,fork()函数创建的子进程,会忠实的将父进程的内存内容进行拷贝,尽管在fork()函数之前定义的变量在各自进程块中的虚拟地址相同,但是不同进程对其的操作是相互隔离的,而不管是fork()之前的全局变量、静态变量还是局部变量,都是如此。

如果想使得两个进程操作同一块物理地址,可以使用共享内存的方式,也可以用内存映射(MMP)的方式。

02 Show me the code

地址相同只是虚拟地址相同,而相同的虚拟地址在不同进程中映射不同的物理地址。

以下面的代码表明,变量初始化为0,先由父进程将其赋值为10,之后再由子进程将其赋值为20,最终的输出来看他们地址相同,却有不同的值。

因为这里的地址是虚拟地址,并不是物理地址,所以两个进程对三个变量的操作从始至终都是互相隔离的。

#include <unistd.h>
#include <stdio.h>
#include <assert.h>


int global_val = 0;         // 全局变量
static int static_val = 0;  // 静态变量

int main() {
    int local_val = 0;      // 局部变量
    
    // 创建子线程
    int id = fork();
    assert(id >= 0);
    
    if (id > 0) {  // 父进程
        global_val = 10;
        static_val = 10;
        local_val = 10;
    } else {       // 子进程
        // 确保父进程操作完毕
        usleep(10);
        global_val = 20;
        static_val = 20;
        local_val = 20;
    }
    
    // 确保父子进程均操作完毕
    sleep(1);
    
    // 打印结果
    if (id > 0) {
        printf("pid= %d\n", getpid());
        printf("global_val地址:%x, 值:%d\n", &global_val, global_val);
        printf("static_val地址:%x, 值:%d\n", &static_val, static_val);
        printf("local_val地址:%x, 值:%d\n", &local_val, local_val);
        
    } else {
        sleep(1);
        printf("pid= %d\n", getpid());
        printf("global_val地址:%x, 值:%d\n", &global_val, global_val);
        printf("static_val地址:%x, 值:%d\n", &static_val, static_val);
        printf("local_val地址:%x, 值:%d\n", &local_val, local_val);
    }
    
    // 确保均打印完毕
    sleep(2);
    
    return 0;
}

03 输出

pid= 54317

global_val地址:2040, 值:10

static_val地址:2044, 值:10

local_val地址:efbff548, 值:10

pid= 54324

global_val地址:2040, 值:20

static_val地址:2044, 值:20

local_val地址:efbff548, 值:20

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值