随笔 - 632  文章 - 17  评论 - 54  阅读 - 93万

使用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   飘杨......  阅读(222)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
历史上的今天:
2014-11-19 this computer meets the requirements for HAXM,but intel Virtualization Technology (VT-x) is not turned on
2013-11-19 移动产品设计书籍推荐
< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5

点击右上角即可分享
微信分享提示