使用mmap函数建立共享映射区,实现两个不相干的进程之间通讯


一、概述

  案例:使用mmap建立共享映射区,实现两个不相干的进程之间通讯。 

存储映射I/O (Memory-mapped I/O) 使一个磁盘文件与存储空间中的一个缓冲区相映射。从缓冲区中取数据,就相当于读文件中的相应字节;将数据写入缓冲区,则会将数据写入文件。这样,就可在不使用read和write函数的情况下,使用地址(指针)完成I/O操作。
使用存储映射这种方法,首先应通知内核,将一个指定文件映射到存储区域中。这个映射工作可以通过mmap函数来实现。
mmap函数
?函数作用:
建立存储映射区
?函数原型
   void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
?函数返回值:
?成功:返回创建的映射区首地址;
?失败:MAP_FAILED宏
?参数:    
?addr:     指定映射的起始地址, 通常设为NULL, 由系统指定
?length:映射到内存的文件长度
?prot:    映射区的保护方式, 最常用的:
?读:PROT_READ
?写:PROT_WRITE
?读写:PROT_READ | PROT_WRITE
?flags:    映射区的特性, 可以是
?MAP_SHARED: 写入映射区的数据会写回文件, 且允许其他映射该文件的进程共享。
?MAP_PRIVATE: 对映射区的写入操作会产生一个映射区的复制(copy-on-write), 对此区域所做的修改不会写回原文件。
?fd:由open返回的文件描述符, 代表要映射的文件。
?offset:以文件开始处的偏移量, 必须是4k的整数倍, 通常为0, 表示从文件头开始映射。

  注意事项:

    映射区文件必须存在,并且映射区文件不能是空文件。

二、代码示例

  1.向共享映射区中写入 

//使用mmap函数完成两个不相干进程间通信
#include 
#include 
#include <string.h>
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
    //使用mmap函数建立共享映射区
    //void *mmap(void *addr, size_t length, int prot, int flags,
    //              int fd, off_t offset);
    int fd = open("./test.log", O_RDWR);
    if(fd<0)
    {
        perror("open error");
        return -1;
    }

    int len = lseek(fd, 0, SEEK_END);

    //建立共享映射区
    void * addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if(addr==MAP_FAILED)
    {
        perror("mmap error");
        return -1;
    }
    
    memcpy(addr, "0123456789", 10);

    return 0;
}

  2.从共享映射区中读取

//使用mmap函数完成两个不相干进程间通信
#include 
#include 
#include <string.h>
#include 
#include 
#include 
#include 
#include 
#include 

int main()
{
    //使用mmap函数建立共享映射区
    //void *mmap(void *addr, size_t length, int prot, int flags,
    //              int fd, off_t offset);
    int fd = open("./test.log", O_RDWR);
    if(fd<0)
    {
        perror("open error");
        return -1;
    }

    int len = lseek(fd, 0, SEEK_END);

    //建立共享映射区
    void * addr = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    if(addr==MAP_FAILED)
    {
        perror("mmap error");
        return -1;
    }

    char buf[64];
    memset(buf, 0x00, sizeof(buf));
    memcpy(buf, addr, 10);
    printf("buf=[%s]\n", buf);

    return 0;
}

三、展示效果