文档章节

使用内存文件映射实现共享内存

mickelfeng
 mickelfeng
发布于 2017/09/11 16:05
字数 694
阅读 46
收藏 0

 文件内存映射(mmap)

// 文件内存映射
#include <iostream>
#include <string>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
using namespace std;

// 主函数
int main(int argc,char* argv[])
{
    // 文件描述符
    int fd;

    // 文件映射的地址
    void *addr;

    // 文件状态信息
    struct stat f_st;

    // 打开一个文件
    fd = open("1.txt", O_RDONLY);

    // 得到文件的状态信息,目的是为了下一步取得文件大小
    fstat(fd, &f_st);

    // 进行文件内存映射
    addr = mmap(NULL, f_st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);

    /* 判断是否映射成功 */
    if(addr == MAP_FAILED)
        return -1;

    // 打印文件的内容
    printf("%s", addr);

    /* 解除映射 */
    munmap(addr, f_st.st_size);

    close(fd);
}

不使用IPC中的共享内存(shm),使用内存文件映射的方式来实现共享内存

共享内存写入者:

// 使用文件内存映射进行内存共享  
#include <iostream>  
#include <string>  
#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <fcntl.h>  
#include <sys/mman.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
using namespace std;  
  
// 用户自定义的一个数据结构  
struct user_st  
{  
    int len;  
    char buffer[2048];  
};  
  
// 共享内存写入者  
int Writer(int argc, char** argv)  
{  
    int fd;  
    user_st * use_data;  
  
    // 创建并打开一个文件(如果文件存在那么清空它),用于内存共享  
    fd=open(argv[1],O_CREAT|O_RDWR|O_TRUNC,00777);  
  
    // 移动文件指针  
    lseek(fd,sizeof(user_st)-1,SEEK_SET);  
  
    // 往文件中写入数据,目的是为了让文件产生这么长的空间,否则写入读取的时候会出现错误  
    write(fd,"",1);  
  
    // 进行内存映射,注意参数:PROT_READ|PROT_WRITE表示可读写,MAP_SHARED表示映射内存用于共享  
    use_data = (user_st*) mmap( NULL,sizeof(user_st),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0 );  
  
    // 关闭文件描述符(注意,虽然文件描述符关闭了,但是映射的内存仍然可用)  
    // 因为在mmap的内部会增加文件对象的引用计数  
    close( fd );  
  
    // 往共享内存中写入数据  
    strcpy(use_data->buffer,"hello world!");  
  
    printf("Write data to Shared Memory!\n");  
  
    sleep(10);  
  
    // 卸载内存文件映射  
    munmap(use_data,sizeof(user_st));  
  
    return 0;  
}  
  
int main(int argc, char** argv) // map a normal file as shared mem:  
{  
    return Writer(argc,argv);  
}  

共享内存读取者:

// 使用文件内存映射进行内存共享  
#include <iostream>  
#include <string>  
#include <unistd.h>  
#include <stdlib.h>  
#include <stdio.h>  
#include <string.h>  
#include <fcntl.h>  
#include <sys/mman.h>  
#include <sys/types.h>  
#include <sys/stat.h>  
using namespace std;  
  
// 用户自定义的一个数据结构  
struct user_st  
{  
    int len;  
    char buffer[2048];  
};  
  
// 共享内存读取者  
int Reader(int argc, char** argv)  
{  
    int fd;  
  
    user_st *use_data;  
  
    // 打开文件  
    fd=open( argv[1],O_CREAT|O_RDWR,00777 );  
  
    // 进行内存映射,映射的大小是sizeof(user_st)  
    use_data = (user_st*)mmap(NULL,sizeof(user_st),PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);  
  
    // 关闭文件  
    close(fd);  
  
    // 读取共享内存  
    printf( "buffer: %s;\n",use_data->buffer );  
  
    // 卸载内存映射  
    munmap( use_data,sizeof(user_st) );  
}  
  
int main(int argc, char** argv) // map a normal file as shared mem:  
{  
    return Reader(argc,argv);  
}  

 

本文转载自:http://blog.csdn.net/nb_vol_1/article/details/51916563

共有 人打赏支持
mickelfeng

mickelfeng

粉丝 231
博文 2690
码字总数 572923
作品 0
成都
高级程序员
私信 提问
进程通信:共享内存

1.System V共享内存: 系统V共享内存指的是把所有共享数据放在共享内存区域(IPC shared memory region),任何想要访问该数据的进程都必须在本进程的地址空间新增一块内存区域,用来映射存放...

满小茂
2016/10/22
23
0
Linux进程间通信源码剖析,共享内存(shmget()、shmat()、shmdt()及shmctl())

地址:http://www.ibm.com/developerworks/cn/linux/l-ipc/part5/index2.html 系统调用mmap()通过映射一个普通文件实现共享内存。系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享...

长平狐
2012/06/12
1K
0
Linux环境进程间通信(五) 共享内存(下)

系统调用mmap()通过映射一个普通文件实现共享内存。系统V则是通过映射特殊文件系统shm中的文件实现进程间的共享内存通信。也就是说,每个共享内存区域对应特殊文件系统shm中的一个文件(这是...

sty124578
01/29
0
0
Linux进程间通信—— 内存映射

Linux环境进程间通信(五): 共享内存(上) 共享内存可以说是最有用的进程间通信方式,也是最快的IPC形式。两个不同进程A、B共享内存的意思是,同一块物理内存被映射到进程A、B各自的进程地...

li_wen01
2017/07/29
0
0
System.IO之内存映射文件共享内存

内存映射文件是利用虚拟内存把文件映射到进程的地址空间中去,在此之后进程操作文件,就像操作进程空间里的地址一样了,比如使用c语言的memcpy等内存操作的函数。这种方法能够很好的应用在需...

长平狐
2012/06/08
180
0

没有更多内容

加载失败,请刷新页面

加载更多

js垃圾回收机制和引起内存泄漏的操作

JS的垃圾回收机制了解吗? Js具有自动垃圾回收机制。垃圾收集器会按照固定的时间间隔周期性的执行。 JS中最常见的垃圾回收方式是标记清除。 工作原理:是当变量进入环境时,将这个变量标记为“...

Jack088
昨天
16
0
大数据教程(10.1)倒排索引建立

前面博主介绍了sql中join功能的大数据实现,本节将继续为小伙伴们分享倒排索引的建立。 一、需求 在很多项目中,我们需要对我们的文档建立索引(如:论坛帖子);我们需要记录某个词在各个文...

em_aaron
昨天
24
0
"errcode": 41001, "errmsg": "access_token missing hint: [w.ILza05728877!]"

Postman获取微信小程序码的时候报错, errcode: 41001, errmsg: access_token missing hint 查看小程序开发api指南,原来access_token是直接当作parameter的(写在url之后),scene参数一定要...

两广总督bogang
昨天
30
0
MYSQL索引

索引的作用 索引类似书籍目录,查找数据,先查找目录,定位页码 性能影响 索引能大大减少查询数据时需要扫描的数据量,提高查询速度, 避免排序和使用临时表 将随机I/O变顺序I/O 降低写速度,占用磁...

关元
昨天
13
0
撬动世界的支点——《引爆点》读书笔记2900字优秀范文

撬动世界的支点——《引爆点》读书笔记2900字优秀范文: 作者:挽弓如月。因为加入火种协会的读书活动,最近我连续阅读了两本论述流行的大作,格拉德威尔的《引爆点》和乔纳伯杰的《疯传》。...

原创小博客
昨天
34
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部