Linux笔记(19)-进程间通信(内存映射区)

  1. 内存映射区:将磁盘上的数据映射到内存上,于是可以不通过io文件,而是操作内存即可操作文件
1. 创建内存映射区 -- mmap函数
    void *mmap(void *addr,      //映射区首地址,传NULL,由系统自动识别
                size_t length,  //映射区的大小,一般为文件的大小(实际上分配的是4K的整数倍),不能为0
                int prot,       //映射区的权限:PROT_EXEC,PROT_READ<必须要有>,PROT_WRITE,PROT_NONE
                int flags,      //MAP_SHARED || MAP_PRIVATE
                                //  shared会修改了内存数据将同步到磁盘,private则不会
                int fd,         //需要映射到内存区的文件操作符,通过open函数得到
                off_t offset    //映射文件时的偏移量,即从文件中的某处开始映射,必须为4K(4096)的整数倍或0
                );
2. 返回值:
    a. 调用成功:返回指针,指向内存映射区的首地址
    b. 调用失败:返回MAP_FAILED <即(void *) -1>
  1. 释放内存映射区:munmap函数
1. 函数原型:
    int munmap(void *addr, size_t length);
2. 参数:
    addr:内存映射区首地址,即mmap的返回值
    length:释放映射区大小,即mmap的第二个参数
3. 返回值:
    -1:函数调用失败,一般为参数错误
    0:函数调用成功
  1. mmap注意事项
1. 不能队mmap函数的返回值指针进行++或--等操作,否则munmap函数将无法释放内存映射区
2. open文件指定的权限需要大于等于mmap函数prot的权限<read/write>
3. mmap函数offset参数必须是4096的整数倍或0
4. mmap函数的length参数不能小于等于0
5. mmap函数的prot参数必须带有READ
6. mmap函数后关闭原来的fd,队mmap映射区没有影响
7. 对ptr指针进行越界操作时,如果原本内存被占用,则产生段错误。即在内存映射区中的内容才可以同步到文件中去
  1. 有血缘关系的进程间通信<非阻塞>
1. 父子进程间永远共享:
    a. 文件描述符
    b. 内存映射区
2. 父进程在创建内存映射区后,创建子进程,父子进程都是通过mmap返回值ptr进行操作
3. 不再使用read/write进行文件io操作,直接操作内存
4. 数据直接在内存中交换,效率高,但是不是阻塞的。
  1. 仅有血缘关系进程间通信:匿名映射区<非阻塞>
1. 创建时不再传入打开文件的fd
    a. 首先指定内存映射区大小
        int len = 4096;
    b. 调用mmap函数
        void *ptr = mmap(NULL, len, PROT_READ | PROT_WRIET, MAP_SHARED | MAP_ANON, -1, 0);
        在映射区flag中添上MAP_ANON表明匿名内存映射区,fd位置传入-1
2. 释放内存映射区时
    munmap(ptr, len);//同样使用之前的参数
  1. 无血缘关系进程间通信:只能通过磁盘文件创建内存映射区<非阻塞>
1. 打开的磁盘文件作为两个无血缘关系进程建立了桥梁
2. 例如:进程A(a.c)和进程B(b.c)
    <1>. a.c文件
        int fd = open("file.txt");
        void *ptr = mmap(...,fd,0);
        对ptr进行读写操作
    <2>. b.c文件
        int fd1 = open("file.txt");
        void *ptr1 = mmap(...,fd1,0);
        对ptr1进行读写操作
3. 在对ptr指针进行读写操作时,不应直接对ptr进行操作,而是复制其指针位置,然后对复制的指针进行操作
    char *p = (char *)ptr;
    p = p + 1024;
    strcpy(p,"hello world!\n");//写操作
    
    //或者读操作
    print("%s", (char *)p);
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值