• Linux进程共享通信 -- mmap实现


    https://blog.csdn.net/y396397735/article/details/50651633

    使用mmap内存映射实现一端写,另一端读的进程间通信


    写端代码write.c

    /*write.c*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    /*映射内存大小*/
    #define MAPLEN 0x100
    /*定义一个学生信息结构体*/
    struct STU
    {
        int id;
        char name[20];
        char sex;
    };
    /*出错信息统一处理函数*/
    void sys_err(char *str, int exitno)
    {
        perror(str);
        exit(exitno);
    }
    
    int main(int argc, char*argv[])
    {
        struct STU *pm;//STU结构体指针
        int fd, i = 0;
        if(argc < 2){
            printf("args error
    ");
            exit(1);
        }
    
        fd = open(argv[1], O_RDWR | O_CREAT, 0777); //打开一文件
        if(fd < 0){
            sys_err("open", 1);
        }
    
        if(lseek(fd, MAPLEN - 1, SEEK_SET) < 0){//文件偏移至分配的内存地址末端
            sys_err("lseek", 3);
        }
    
        if(write(fd, "", 1) < 0){  //末端赋值为''
            sys_err("write", 4);
        }
        /*将文件映射至进程的地址空间*/
        pm = mmap(NULL, MAPLEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if(pm == MAP_FAILED){
            sys_err("mmap", 2);
        }
        /*关闭文件描述符*/
        close(fd);
        /*对文件进行写入操作*/
        while(1){
            pm->id = i;
            sprintf(pm->name, "yu-%d", i);
            if(i % 2 == 0){
                pm->sex = 'm';
            }else{
                pm->sex = 'w';
            }
            i++;
            sleep(1);
        }
        munmap(pm, MAPLEN);
    
        return 0;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    读端代码read.c

    /*read.c*/
    #include <stdio.h>
    #include <stdlib.h>
    #include <fcntl.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    
    #define MANLEN 0x1000
    
    struct STU
    {
        int id;
        char name[20];
        char sex;
    };
    
    void sys_err(char *str, int exitno)
    {
        perror(str);
        exit(exitno);
    }
    
    int main(int argc, char *argv[])
    {
        struct STU *pm;
        int fd, i = 0;
        if (argc < 2) {
            printf("args error
    ");
            exit(1);
        }
    
        fd = open(argv[1], O_RDWR);
        if (fd < 0){
            sys_err("open", 1); 
        }
    
        pm = mmap(NULL, MAPLEN, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if(pm == MAP_FAILED){
            sys_err("mmap", 2);
        }
        /*关闭文件*/
        close(fd);
        /*删除文件*/
        unlink(argv[1]);
        /*在内存中读数据*/
        while(1){
            printf("%d
    ", pm->id);
            printf("%s
    ", pm->name);
            printf("%c
    ", pm->sex);
            sleep(1);
        }
        munmap(pm, MAPLEN);
    
        return 0;
    }
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57

    执行过程:

    yu@ubuntu:~/Linux/211/tongxin$ ls
    read.c  write.c
    yu@ubuntu:~/Linux/211/tongxin$ gcc -o write write.c
    yu@ubuntu:~/Linux/211/tongxin$ gcc -o read read.c
    yu@ubuntu:~/Linux/211/tongxin$ ls
    read  read.c  write  write.c
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    此时执行写操作

    yu@ubuntu:~/Linux/211/tongxin$ ./write myfile
    //在向myfile文件中写数据
    • 1
    • 2

    另开一终端到当前目录,执行如下读操作:

    yu@ubuntu:~/Linux/211/tongxin$ ls
    read  read.c  write  write.c  myfile
    yu@ubuntu:~/Linux/211/tongxin$ ./read myfile
    6
    yu-6
    m
    7
    yu-7
    w
    ^C//读取写入的内容Ctrl+C退出
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    退出后,执行ls,可发现myfile文件已删除

    yu@ubuntu:~/Linux/211/tongxin$ ls
    read  read.c  write  write.c
    • 1
    • 2
    版权声明:个人学习之路,若有误,欢迎指正。其中一些博文被证明有错误的地方,最近比较忙,没时间更正,谨慎参考!! https://blog.csdn.net/y396397735/article/details/50651633
  • 相关阅读:
    Git for Windows之基础环境搭建与基础操作
    TFS2018环境搭建一单实例安装(适用于小型团队)
    TFS2018环境搭建一硬件要求
    Proxy代理模式(结构型模式)
    Flyweight享元模式(结构型模式)
    Facade外观模式(结构性模式)
    Decorator装饰者模式(结构型模式)
    Composite组合模式(结构型模式)
    mybatis中 #{} 和 ${} 的区别
    解决mybatis中#{}导致的The error may involve defaultParameterMap的问题
  • 原文地址:https://www.cnblogs.com/diegodu/p/9262314.html
Copyright © 2020-2023  润新知