• 浅析Linux进程间通信方式之磁盘映射(mmap)


    作用

    一对多或者多对多进行进程通信。


    特点

    1. 支持磁盘文件匿名映射;
    2. 效率高;
    3. 消息可自定义格式;
    4. 消息传递需要实时传递(由于是修改地址内容来传递消息,如果无及时读取,之前消息会被覆盖)。

    使用

    建立映射区

    1. void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
    2. addr 地址,填NULL
    3. length 长度 要申请的映射区的长度
    4. prot 权限
    5. PROT_READ 可读
    6. PROT_WRITE 可写
    7. flags 标志位
    8. MAP_SHARED 共享的 -- 对映射区的修改会影响源文件
    9. MAP_PRIVATE 私有的
    10. fd 文件描述符 需要打开一个文件
    11. offset 指定一个偏移位置 ,从该位置开始映射
    12. 返回值
    13. 成功 返回映射区的首地址
    14. 失败 返回 MAP_FAILED ((void *) -1)

    释放映射区

    1. int munmap(void *addr, size_t length);
    2. addr 映射区的首地址
    3. length 映射区的长度
    4. 返回值
    5. 成功 返回0
    6. 失败 返回 -1

    关于mmap需要思考的问题

    1. 如果文件偏移量随便填个数会怎么样?
    2. 如果文件描述符先关闭,对mmap映射有没有影响?
    3. 如果更改mem变量的地址,释放的时候munmap,传入mem还能成功吗?
    4. 如果对mem越界操作会怎么样?
    5. open的时候,可以新创建一个文件来创建映射区吗?
    6. open文件选择O_WRONLY,可以吗?
    7. 当选择MAP_SHARED的时候,open文件选择O_RDONLY,prot可以选择PROT_READ|PROT_WRITE吗?

    拓展文件大小

    1. int truncate(const char *path, off_t length);
    2. path 要拓展的文件
    3. length 要拓展的长度

    实例

    1. //mmapsend.c
    2. #include <sys/types.h>
    3. #include <sys/ipc.h>
    4. #include <sys/mman.h>
    5. #include <stdio.h>
    6. #include <string.h>
    7. #include <unistd.h>
    8. #include <fcntl.h>
    9. int main()
    10. {
    11. int fd = open("./a.txt",O_RDWR);
    12. void *str = mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    13. // 写入数据
    14. strcpy(str,"hello world");
    15. return 0;
    16. }
    1. //mmaprcv.c
    2. #include <sys/types.h>
    3. #include <sys/ipc.h>
    4. #include <sys/mman.h>
    5. #include <stdio.h>
    6. #include <string.h>
    7. #include <fcntl.h>
    8. int main()
    9. {
    10. int fd = open("./a.txt",O_RDWR|O_CREAT,0777);
    11. void *str = mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    12. printf("%s\n",(char*)str);
    13. return 0;
    14. }


    注意

    • 文件a.txt一般需要存在且不能为空文件;如果想创建文件,需要使用文件拓展函数进行文件拓展
    1. #include <sys/types.h>
    2. #include <sys/ipc.h>
    3. #include <sys/mman.h>
    4. #include <stdio.h>
    5. #include <string.h>
    6. #include <fcntl.h>
    7. int main()
    8. {
    9. int fd = open("./a.txt",O_RDWR);
    10. if(fd<0)
    11. {
    12. fd = open("./a.txt",O_RDWR|O_CREAT,0666);
    13. truncate("./a.txt",1024);//文件大小拓展
    14. }
    15. void *str = mmap(NULL,1024,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    16. printf("%s\n",(char*)str);
    17. return 0;
    18. }
    • 偏移量建议给0;
    • 当选择MAP_SHARED的时候,open文件选择O_RDONLY|PROT_WRITE,但是映射的进程内存只支持读;
    • 如果文件描述符先关闭,再mmap映射,会报段错误;
    • 如果文件描述符==-1,再mmap映射,磁盘映射只支持有公共祖先进程通信(匿名映射);
  • 相关阅读:
    tomcat 7 Request请求参数中文乱码问题
    采用BeautifulSoup&&pqQuery&&xpath三种方法爬取电影详情页
    Java GC机制 —— 个人笔记
    RSA加密与解密原理
    Android OpenGL ES 总结之FBO
    7.网络原理之TCP_IP(下)
    0.开发中的问题与解决方案
    JavaScript算法43- 分类求和并作差(leetCode:100103easy)周赛
    图解计算机内部的高速公路 —— 总线系统
    科技云报道:实现元宇宙,英伟达从打造基础建设平台开始
  • 原文地址:https://blog.csdn.net/Mr_Yang12306/article/details/132623534