POSIX 共享内存和 系列函数
在前面介绍了system v 共享内存的相关知识,现在来稍微看看posix 共享内存 和系列函数。
共享内存简单来说就是一块真正的物理内存区域,可以使用一些函数将这块区域映射到进程的地址空间进行读写,而posix 共享内存与system v 共享内存不同的是它是用虚拟文件系统(tmpfs)实现的,已经挂载在/dev/shm 下面。man 7 shm_overview
下面来看系列函数,编译时候加上 -lrt 选项,即连接librt 库 (实时库)
功能:用来创建或打开一个共享内存对象
原型 int shm_open(const char *name, int oflag, mode_t mode);
参数
name:共享内存对象的名字,必须以/打头,并且后续不能有其它/ ,形如/somename长度不能超过NAME_MAX(255)
oflag:与open函数类似,可以是O_RDONLY、O_RDWR,还可以按位或上O_CREAT、O_EXCL、O_TRUNC等。
mode:此参数总是需要设置,如果oflag没有指定了O_CREAT,可以指定为0
返回值:成功返回非负整数文件描述符;失败返回-1
注意,不存在所谓的shm_close 函数,可以直接使用close 来关闭文件描述符。
功能:修改共享内存对象大小,shm_open不像shmget一样可以设置共享内存的大小,但可以使用ftruncate 设置大小。
原型 int ftruncate(int fd, off_t length);
参数
fd: 文件描述符
length:长度
返回值:成功返回0;失败返回-1
功能:获取共享内存对象信息
原型
int fstat(int fd, struct stat *buf);
参数
fd: 文件描述符
buf:返回共享内存状态
返回值:成功返回0;失败返回-1
struct stat 可以参考这里。
类似 shmctl(, IPC_STAT,);
功能:删除一个共享内存对象
原型 int shm_unlink(const char *name);
参数
name: 共享内存对象的名字
返回值:成功返回0;失败返回-1
shm_unlink 类似 shmctl(, IPC_RMID, );
功能:将共享内存对象映射到进程地址空间。
原型 void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
参数
addr: 要映射的起始地址,通常指定为NULL,让内核自动选择
len:映射到进程地址空间的字节数
prot:映射区保护方式
flags:标志
fd:文件描述符
offset:从文件头开始的偏移量
返回值:成功返回映射到的内存区的起始地址;失败返回-1
在前面曾经介绍了mmap 函数 将文件映射到进程地址空间的作用,其实它还可以将共享内存对象映射到进程地址空间,类似shmat的作用,只是传入的文件描述符fd 是shm_open
返回的。同样地,解除映射可以用munmap,类似shmdt 的作用。
下面写几个程序来演示一下:
shm_open.c
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 32 33 |
#include<stdio.h>
#include<stdlib.h> #include<sys/ipc.h> #include<sys/types.h> #include<unistd.h> #include<errno.h> #include<fcntl.h> #include<sys/stat.h> #include<sys/mman.h> #define ERR_EXIT(m) \ int main(void) struct stat buf; printf("size=%ld, mode=%o\n", buf.st_size, buf.st_mode & 0777); |
simba@ubuntu:~/Documents/code/linux_programming/UNP/posix$ ./shm_open
size=36, mode=664
simba@ubuntu:~/Documents/code/linux_programming/UNP/posix$ ls -l /dev/shm/xyz
-rw-rw-r-- 1 simba simba 36 Jun 16 15:01 /dev/shm/xyz
即创建了一个36字节的共享内存段,在/dev/shm 目录下。
shm_write.c
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
#include<stdio.h>
#include<stdlib.h> #include<sys/ipc.h> #include<sys/types.h> #include<unistd.h> #include<errno.h> #include<fcntl.h> #include<sys/stat.h> #include<sys/mman.h> #include<string.h> #define ERR_EXIT(m) \ typedef struct stu int main(void) struct stat buf; printf("size=%ld, mode=%o\n", buf.st_size, buf.st_mode & 0777); STU *p; strcpy(p->name, "test"); close(shmid); |
simba@ubuntu:~/Documents/code/linux_programming/UNP/posix$ ./shm_write
size=36, mode=664
simba@ubuntu:~/Documents/code/linux_programming/UNP/posix$ od -c /dev/shm/xyz
0000000 t e s t \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000020 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0
0000040 024 \0 \0 \0
0000044
使用mmap 将共享内存映射到进程地址空间,将shmid 传入fd 参数,其余跟文件映射没什么区别,od -c查看可以看到写入的东西。
shm_read.c
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
#include<stdio.h>
#include<stdlib.h> #include<sys/ipc.h> #include<sys/types.h> #include<unistd.h> #include<errno.h> #include<fcntl.h> #include<sys/stat.h> #include<sys/mman.h> #include<string.h> #define ERR_EXIT(m) \ typedef struct stu int main(void) struct stat buf; printf("size=%ld, mode=%o\n", buf.st_size, buf.st_mode & 0777); STU *p; printf("name=%s age=%d\n", p->name, p->age); |
simba@ubuntu:~/Documents/code/linux_programming/UNP/posix$ ./shm_read
size=36, mode=664
name=test age=20
即读取到了共享内存的数据,注意,读取数据后共享内存的数据还是存在的,除非被覆盖了。
参考:《UNP》
POSIX 共享内存和 系列函数的更多相关文章
- System V 共享内存 和 系列函数
跟消息队列一样,共享内存也有自己的数据结构,如下: struct shmid_ds { struct ipc_perm shm_perm; /* Ownership and permission ...
- Linux IPC实践(10) --Posix共享内存
1. 创建/获取一个共享内存 #include <sys/mman.h> #include <sys/stat.h> /* For mode constants */ #inc ...
- POSIX共享内存
DESCRIPTION 共享内存是最快的可用IPC形式.它允许多个不相关(无亲缘关系)的进程去访问同一部分逻辑内存. 如果需要在两个进程之间传输数据,共享内存将是一种效率极高的解决方案.一旦这样的内存 ...
- Posix共享内存区
1.概述 Posix提供了两种在无亲缘关系进程间共享内存区的方法: (1)内存映射文件:先有open函数打开,然后调用mmap函数把得到的描述符映射到当前进程地址空间中的一个文件(上一篇笔记所用到的就 ...
- 细说linux IPC(四):posix 共享内存
[版权声明:尊重原创.转载请保留出处:blog.csdn.net/shallnet 或 .../gentleliu,文章仅供学习交流,请勿用于商业用途] 上一节讲了由open函数打开一 ...
- linux c编程:Posix共享内存区
Posix共享内存区:共享内存是最快的可用IPC形式.它允许多个不相关(无亲缘关系)的进程去访问同一部分逻辑内存.如果需要在两个进程之间传输数据,共享内存将是一种效率极高的解决方案.一旦这样的内存区映 ...
- 第三十五章 POSIX共享内存
POSIX共享内存函数介绍 shm_open 功能: 用来创建或打开一个共享内存对象 原型: int shm_open(const char *name, int oflag, mode_t mode ...
- linux网络编程之posix共享内存
今天继续研究posix IPC对象,这次主要是学习一下posix共享内存的使用方法,下面开始: 下面编写程序来创建一个共享内存: 编译运行: 那posix的共享内存存放在哪里呢?上节中学的posix的 ...
- php实现共享内存进程通信函数之_shm
前面介绍了php实现共享内存的一个函数shmop,也应用到了项目中,不过shmop有局限性,那就是只支持字符串类型的:sem经过我的测试,是混合型,支持数组类型,可以直接存储,直接获取,少了多余的步骤 ...
随机推荐
- 解决duilib使用zip换肤卡顿的问题(附将资源集成到程序中的操作方法)
转载请说明原出处,谢谢~~ 今天在做单子是.客户要求做换肤功能,为此我专门写了一个换肤函数,而且把各种皮肤资源压缩为各个zip文件来换肤.可是客户反映程序执行缓慢,我測试后发现的确明显能够看出慢了不少 ...
- Android -- 文件扫描
启动MediaScanner服务,扫描媒体文件,程序通过发送下面的Intent启动MediaScanner服务. 扫描指定文件 public void scanFile(Context ctx, St ...
- 25个iptables常用示例
本文将给出25个iptables常用规则示例,这些例子为您提供了些基本的模板,您可以根据特定需求对其进行修改调整以达到期望. 格式 iptables [-t 表名] 选项 [链名] [条件] [-j ...
- matlab中,怎样把矩阵中所有的0改为2
一句话搞定:>> a(find(a==0))=[2]:把矩阵中所有的0改为2
- [Javascript] Closure Cove, Common mistake
They’ve got a problem with their existing code, which tries to use a closure. Check it out: function ...
- Carrer Day有感
2013年10月17日 一.永不放弃,痼疾必须自己克服,否则永远有阴影. 二.若长期无法取得进展,应该换一种方式. 大Boss确实有水平,答到点子上且照顾到听众面子,强.很多话掷地有声,发人深省,比如 ...
- CentOS6.X下安装配置独立SVN服务器Subversion server
Subversion(简称SVN,svn),一个开放源码的版本号控制系统.相较于RCS.CVS,它採用了分支管理系统,它的设计目标就是代替CVS.互联网上非常多版本号控***务已从CVS转移到Subv ...
- ArcGIS高程Z值的去除方法
在ArcGIS中,我们常用的几何类型有点.线.面.体(体,在涉及三维的情况下使用),但在这之外,可能会遇到带ZM的类型,如图所示,面ZM,它与面类似,但比面多两个字段. 在编辑中查看草图属性可看到Z值 ...
- java 笔试之在线模拟
网站地址: https://www.nowcoder.com
- 全局安装 vue
通过npm命令安装vuejs在用 Vue.js 构建大型应用时推荐使用 NPM 安装,NPM 能很好地和诸如 Webpack 或Browserify 的 CommonJS 模块打包器配合使用.(以下操 ...