使用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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/mman.h>

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;
}

 

三、展示效果

 

posted on 2021-11-19 10:40  飘杨......  阅读(276)  评论(0)    收藏  举报