多进程共享内存

多进程共享内存

共享内存:

在内存模型中,内核空间的下面有一块空间叫做内存映射段,包括文件映射(如映射动态链接库,程序运行时,将动态库加载到内存,并映射到程序的地址空间)、匿名映射,实现内存共享。

20221223160308

mmap:一种内存映射文件的方法,将内核中的特定部分内存映射到用户级进程中去,相比普通的read/write少一次拷贝,内核直接把文件数据从磁盘拷贝到共享内存就用户就行访问,使得这份数据不需要同时保留在两个页缓冲中;而write需要先从磁盘拷贝到页缓冲,再从页缓冲拷贝到用户进程;

所以你会发现文件利用读写函数下载时,内存变少,buff/cache变大

重定向

本质是修改该进程中files_struct的元素指向。引用链接

20221223163300

实现

fork()写时复制

注意:

  • vfork是直接共享父进程的虚拟空间和物理空间,类似于线程。
  • fork不共享父进程的空间,会进行正文段、数据段、堆、栈的写时复制
  • fork()时,子进程和父进程是共享内存的,但是内存只要是共享的,那一定是写保护的
  • 当父进程和子进程进行写操作时,内核把这个页复制到一个新的页面,标记为对该进程可写,原来的页面仍然是写保护
  • 一个写保护的页面只有一个属主时,当这个属主进程访问这个页面时,内核将这个页面标记为对这个进程可写
#define _GNU_SOURCE 
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
 #include <sys/mman.h> // 共享内存
void *shm_mmap_alloc(int size)
{
    /**
     * PROT_READ|PROT_WRITE:对文件可读可写,不可执行
     * MAP_ANON | MAP_SHARED: 匿名共享,就像是匿名管道通信
     * fd=open(name, flag, mode);  这里为-1表示匿名文件,通过ls是无法查看的,就像匿名的管道无法查看,0是标准输入->键盘,1是标准输出->显示器,2是标准错误->显示器
     */

    //  多个进程可以读同一个文件
    void *addr = mmap(NULL, size, PROT_READ | PROT_WRITE,
                      MAP_ANON | MAP_SHARED, -1, 0);
    // 也可以用下面这种:/dev/zero设备像个黑洞,写多少数据都会被吞掉
    // int fd = open("/dev/zero", O_RDWR);
    // void *addr = mmap(NULL, size, PROT_READ|PROT_WRITE, 
    //     MAP_SHARED, fd, 0);

    if (addr == MAP_FAILED)
    {
        return NULL;
    }

    return addr;
}

int shm_mmap_free(void *addr, int size)
{

    return munmap(addr, size);
}


int main(){
    // 如果只是申明char *addr[1024];父进程是打印不出信息的
    char *addr = (char *)shm_mmap_alloc(1024);

    pid_t pid = fork();
    if (pid == 0)
    { // 子进程写共享内存
        int i = 0;

        while (i < 26)
        {
            addr[i] = 'a' + i++;
            addr[i] = '\0';
            sleep(1);
        }
    }
    else if (pid > 0)
    { // 父进程读共享内存
        int i = 0;
        while (i++ < 26)
        {
            printf("parent: %s\n", addr);
            sleep(1);
        }
    }

    shm_mmap_free(addr, 1024);
    return 0;
}

除了mmap,还有shmget接口实现进程间共享内存通信

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值