Linux IPC实践(10) --Posix共享内存
1. 创建/获取一个共享内存
#include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #include <fcntl.h> /* For O_* constants */ int shm_open(const char *name, int oflag, mode_t mode);
参数:
name: 共享内存名字;
oflag: 与open函数类型, 可以是O_RDONLY, O_WRONLY, O_RDWR, 还可以按位或上O_CREAT, O_EXCL, O_TRUNC.
mode: 此参数总是需要设置, 如果oflag没有指定O_CREAT, 则mode可以设置为0;
返回值:
成功: 返回一个文件描述符;
失败: 返回-1;
注意-Posix IPC名字限制:
1. 必须以”/”开头, 并且后面不能还有”/”, 形如:/file-name;
2. 名字长度不能超过NAME_MAX
3. 链接时:Link with -lrt.
/** 示例: 共享内存的打开与关闭 **/ int main(int argc,char *argv[]) { int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666); if (shmid == -1) err_exit("shmget error"); cout << "share memory open success" << endl; close(shmid); }
2. 修改共享内存大小
int ftruncate(int fd, off_t length);
该函数不仅可用于修改共享内存大小, 而且可以用于修改文件大小
/** 示例: 修改共享内存大小 将其修改为一个Student结构体的大小 **/ struct Student { char name[32]; int age; }; int main(int argc,char *argv[]) { int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666); if (shmid == -1) err_exit("shmget error"); if (ftruncate(shmid, sizeof(Student)) == -1) err_exit("ftruncate error"); cout << "share memory change size success" << endl; close(shmid); }
3. 获取共享内存状态
int fstat(int fd, struct stat *buf);
该函数不仅可用于获取共享内存状态, 而且可以用于获取文件状态, 与前面曾经讲述过的stat, lstat类型;
//stat结构体 struct stat { dev_t st_dev; /* ID of device containing file */ ino_t st_ino; /* inode number */ mode_t st_mode; /* protection */ nlink_t st_nlink; /* number of hard links */ uid_t st_uid; /* user ID of owner */ gid_t st_gid; /* group ID of owner */ dev_t st_rdev; /* device ID (if special file) */ off_t st_size; /* total size, in bytes */ blksize_t st_blksize; /* blocksize for filesystem I/O */ blkcnt_t st_blocks; /* number of 512B blocks allocated */ time_t st_atime; /* time of last access */ time_t st_mtime; /* time of last modification */ time_t st_ctime; /* time of last status change */ };
/** 示例: 获取共享内存的mode和size **/ int main(int argc,char *argv[]) { int shmid = shm_open("/xyz", O_RDWR|O_CREAT, 0666); if (shmid == -1) err_exit("shmget error"); if (ftruncate(shmid, sizeof(Student)) == -1) err_exit("ftruncate error"); struct stat buf; if (fstat(shmid, &buf) == -1) err_exit("lstat error"); // 注意: 获取权限时, 需要&上0777, 而且要以%o, 八进制方式打印 printf("mode: %o\n", buf.st_mode&0777); printf("size: %ld\n", buf.st_size); close(shmid); }
4. 删除一个共享内存对象
int shm_unlink(const char *name);
//示例: int main(int argc,char *argv[]) { shm_unlink("/xyz"); }
5. 共享内存的映射/卸载
#include <sys/mman.h> void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); int munmap(void *addr, size_t length);
参数:
addr: 要映射的起始地址, 通常指定为NULL, 让内核自动选择;
length: 映射到进程地址空间的字节数, 通常是先前已经创建的共享内存的大小;
prot: 映射区保护方式(见下);
flags: 标志(通常指定为MAP_SHARED, 用于进程间通信);
fd: 文件描述符(填为shm_open返回的共享内存ID);
offset: 从文件头开始的偏移量(一般填为0);
prot |
说明 |
PROT_READ |
页面可读 |
PROT_WRITE |
页面可写 |
PROC_EXEC |
页面可执行 |
PROC_NONE |
页面不可访问 |
flags |
说明 |
MAP_SHARED |
变动是共享的 |
MAP_PRIVATE |
变动是私有的 |
MAP_FIXED |
准确解释addr参数, 如果不指定该参数, 则会以4K大小的内存进行对齐 |
MAP_ANONYMOUS |
建立匿名映射区, 不涉及文件 |
mmap返回值:
成功: 返回映射到的内存区的起始地址;
失败: 返回MAP_FAILED;
注意:mmap失败返回EACCES错误的原因:
EACCES A file descriptor refers to a non-regular file.
Or MAP_PRIVATE was requested, but fd is not open for reading.
Or MAP_SHARED was requested and PROT_WRITE is set, but fd is not open
in read/write (O_RDWR) mode. Or PROT_WRITE is set, but the file is append-only.
/** 示例: 向共享内存写入数据 **/ int main(int argc,char *argv[]) { int shmid = shm_open("/xyz", O_RDWR, 0); if (shmid == -1) err_exit("shm_open error"); struct stat buf; if (fstat(shmid, &buf) == -1) err_exit("fstat error"); Student *p = (Student *)mmap(NULL, buf.st_size, PROT_WRITE, MAP_SHARED, shmid, 0); if (p == MAP_FAILED) err_exit("mmap error"); strcpy(p->name, "Hadoop"); p->age = 5; munmap(p, buf.st_size); close(shmid); }
/** 从共享内存读出数据 **/ int main(int argc,char *argv[]) { int shmid = shm_open("/xyz", O_RDONLY, 0); if (shmid == -1) err_exit("shm_open error"); struct stat buf; if (fstat(shmid, &buf) == -1) err_exit("fstat error"); Student *p = (Student *)mmap(NULL, buf.st_size, PROT_READ, MAP_SHARED, shmid, 0); if (p == MAP_FAILED) err_exit("mmap error"); cout << "name: " << p->name << ", age: " << p->age << endl; munmap(p, buf.st_size); close(shmid); }
[附]
-Posix共享内存默认创建在/dev/shm目录下
-可以使用od命令查看共享内存的内容
od -c /dev/shm/xyz
Linux IPC实践(10) --Posix共享内存的更多相关文章
- linux c编程:Posix共享内存区
Posix共享内存区:共享内存是最快的可用IPC形式.它允许多个不相关(无亲缘关系)的进程去访问同一部分逻辑内存.如果需要在两个进程之间传输数据,共享内存将是一种效率极高的解决方案.一旦这样的内存区映 ...
- linux网络编程之posix共享内存
今天继续研究posix IPC对象,这次主要是学习一下posix共享内存的使用方法,下面开始: 下面编写程序来创建一个共享内存: 编译运行: 那posix的共享内存存放在哪里呢?上节中学的posix的 ...
- Linux IPC实践(7) --Posix消息队列
1. 创建/获取一个消息队列 #include <fcntl.h> /* For O_* constants */ #include <sys/stat.h> /* For m ...
- 细说linux IPC(四):posix 共享内存
[版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 上一节讲了由open函数打开一 ...
- Linux进程IPC浅析[进程间通信SystemV共享内存]
Linux进程IPC浅析[进程间通信SystemV共享内存] 共享内存概念,概述 共享内存的相关函数 共享内存概念,概述: 共享内存区域是被多个进程共享的一部分物理内存 多个进程都可把该共享内存映射到 ...
- Posix共享内存区
1.概述 Posix提供了两种在无亲缘关系进程间共享内存区的方法: (1)内存映射文件:先有open函数打开,然后调用mmap函数把得到的描述符映射到当前进程地址空间中的一个文件(上一篇笔记所用到的就 ...
- POSIX共享内存
DESCRIPTION 共享内存是最快的可用IPC形式.它允许多个不相关(无亲缘关系)的进程去访问同一部分逻辑内存. 如果需要在两个进程之间传输数据,共享内存将是一种效率极高的解决方案.一旦这样的内存 ...
- POSIX 共享内存和 系列函数
在前面介绍了system v 共享内存的相关知识,现在来稍微看看posix 共享内存 和系列函数. 共享内存简单来说就是一块真正的物理内存区域,可以使用一些函数将这块区域映射到进程的地址空间进行读写, ...
- 第三十五章 POSIX共享内存
POSIX共享内存函数介绍 shm_open 功能: 用来创建或打开一个共享内存对象 原型: int shm_open(const char *name, int oflag, mode_t mode ...
随机推荐
- 3.1 One-dim Vector Initialtization
vector<int> v(10, -1); //10个-1 v.size(); v.empty(); //is empty?
- C++框架_之Qt的开始部分_概述_安装_创建项目_快捷键等一系列注意细节
C++框架_之Qt的开始部分_概述_安装_创建项目_快捷键等一系列注意细节 1.Qt概述 1.1 什么是Qt Qt是一个跨平台的C++图形用户界面应用程序框架.它为应用程序开发者提供建立艺术级图形界面 ...
- 全新 Kali Linux 系统安装指南
Kali Linux 系统可以说是在安全测试方面最好的开箱即用的 Linux 发行版.Kali 下的很多工具软件都可以安装在大多数的 Linux 发行版中,Offensive Security 团队在 ...
- JAVAEE——BOS物流项目11:在realm中授权、shiro的方法注解权限控制、shiro的标签权限控制、总结shiro的权限控制方式、权限管理
1 学习计划 1.在realm中进行授权 2.使用shiro的方法注解方式权限控制 n 在spring文件中配置开启shiro注解支持 n 在Action方法上使用注解 3.★使用shiro的标签进行 ...
- Redis之(五)持久化
Redis提供了两种持久化的方式: (1)RDB(Redis DataBase)模式,就是在不同的时间点,将Redis存储的数据生成快照并存储到磁盘等介质上: (2)AOF(Append Only F ...
- linux 防火墙操作
root/12345 (只能用ROOT操作)iptables -I INPUT -s x.x.x.x -p tcp --dport 8091 -j ACCEPT #允许x.x.x.x访问本机的80 ...
- Latex 文本编辑技巧
临时取消首行缩进 \noindent 生成随机文本 \usepackage{lipsum} \begin{document} \lipsum \end{document} 多栏模式 \usepacka ...
- python将nan, inf转为特定的数字
最近,处理两个矩阵的点除,得到结果后,再作其他的计算,发现有些内置的函数不work:查看得到的数据,发现有很多nan和inf,导致python的基本函数运行不了,这是因为在除的过程中分母出现0的缘故. ...
- Android开发艺术探索——第二章:IPC机制(中)
Android开发艺术探索--第二章:IPC机制(中) 好的,我们继续来了解IPC机制,在上篇我们可能就是把理论的知识写完了,然后现在基本上是可以实战了. 一.Android中的IPC方式 本节我们开 ...
- EBS开发常用编译命令
一.编译FORM 1.将脚本写成shell脚本 cd $AU_TOP/forms/ZHS export FORMS_PATH=.:$FORMS_PATH:$AU_TOP/forms/ZHS frmcm ...