POSIX共享内存(内存映射)
来源:互联网 发布:淘宝宝贝描述文字 编辑:程序博客网 时间:2024/06/06 17:24
本质:
两个进程访问同一个逻辑内存;
直接访问内存,不用read()/write(),非常方便。
匿名映射文件:
设备 作用 举例/dev/zero永远输出0的设备文件dd if=/dev/zero of=磁盘分区 count=1024 bs=1024/dev/null丢弃一切写入其中数据cat test > /dev/null/dev/fd 记录用户打开的文件描述符ls /dev/fd/
头文件:
sys/mman.h
链接库:
rt
查看:
man shm_overview
ls /dev/shm/
创建:
int shm_open(const char* name,int oflag,mode_t mode);
name:
posix IPC名字。
oflag:
标志:
标志 作用O_CREAT 没有该对象则创建O_EXCL 如果O_CREAT指定,但name不存在,就返回错误O_RDONLY只读O_RDWR 读写O_WRONLY只写O_TRUNC 若存在则截断
mode:
权限。
权限作用S_IWUSR用户/属主写S_IRUSR用户/属主读S_IWGRP组成员写S_IRGRP组成员读S_IWOTH其他用户写S_IROTH其他用户读返回值:
-1-------出错
其他----共享内存描述符
删除:
int shm_unlink(const char* name);
name:
posix IPC名字。
返回值:
-1——出错
0——-成功
修改文件大小:
创建新文件时大小为0,无法映射(存入数据)。
int ftruncater(int fd,off_t length);
fd:
文件描述符。
length:
文件大小。
如果原文件大小比参数length大,超过部分删除。
返回值:
0——成功
-1——失败
建立内存映射:
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset);
start:
映射区的开始地址,一般为NULL(从可移植考虑)。
如果写NULL,就是让系统决定映射区的起始地址。
length:
映射区的长度(以字节为单位;不足一页内存按一页内存处理)。
port:
内存保护标志。
不能与文件的打开模式冲突(打开为读->prot为读;打开为读写->prot为写或读写)。
PROT_EXEC——页内容可被执行
PROT_READ——页内容可被读写
PROT_WRITE——页可被写
PROT_NONE——页不可访问
flags:
映射对象类型。
MAP_SHARED——变动共享
MAP_PRIVATE——变动私有
MAP_ANON———匿名内存映射(与MAP_SHARED一起用)
fd:
文件描述符(不能为套接字和终端的fd)。
-1————匿名内存映射。
offset:
被映射对象内容的起点(偏移量)。
返回值:
MAP_FAILED——失败
非MAP_FAILED——共享内存地址
删除内存映射:
int munmap(void* start,size_t length);
start:
映射内存起始地址。
length:
内存大小。
返回值:
0——成功
-1——失败
注意:
关闭mmap中的文件描述符不能删除内存映射。
同步(类似fflush):
int msync(void* addr,size_t len,int flags);
addr:
映射内存起始地址。
len:
内存大小。
flags:
同步参数:
MS_ASYNC——异步;调用会立即返回。不等到更新的完成。
MS_SYNC——同步;调用会等到更新完成之后返回。
MS_INVALIDATE——通知使用该共享区域进程,数据以改变;在共享内容更改后,使得文件的其他映射失效。
返回值:
0——成功
-1——失败
代码:
创建+修改文件大小:
#include <stdio.h>#include <unistd.h>#include <sys/mman.h>#include <fcntl.h>#include <string.h>int main(int argc,char* argv[]){int fd = shm_open(argv[1],O_CREAT|O_RDWR,0644);ftruncate(fd,atoi(argv[2]));void* buf = NULL;if(( buf = mmap(NULL,BUFSIZ,PROT_WRITE,MAP_SHARED,fd,0)) == MAP_FAILED){perror("mmap error\n");return 1;}}
删除:
#include <stdio.h>#include <unistd.h>#include <sys/mman.h>#include <fcntl.h>#include <string.h>int main(int argc,char* argv[]){shm_unlink(argv[1]);}
读:
#include <stdio.h>#include <unistd.h>#include <sys/mman.h>#include <fcntl.h>#include <string.h>int main(int argc,char* argv[]){int fd = shm_open(argv[1],O_RDONLY,0);void* buf = NULL;if(( buf = mmap(NULL,BUFSIZ,PROT_READ,MAP_SHARED,fd,0)) == MAP_FAILED){perror("mmap error\n");return 1;}printf("%s\n",buf);munmap(buf,BUFSIZ);}
写:
#include <stdio.h>#include <unistd.h>#include <sys/mman.h>#include <fcntl.h>#include <string.h>int main(int argc,char* argv[]){int fd = shm_open(argv[1],O_RDWR,0);void* buf = NULL;if(( buf = mmap(NULL,BUFSIZ,PROT_WRITE,MAP_SHARED,fd,0)) == MAP_FAILED){perror("mmap error\n");return 1;}strcpy(buf,argv[2]);munmap(buf,BUFSIZ);}
亲缘进程间的匿名映射:
#include <stdio.h>#include <unistd.h>#include <sys/mman.h>#include <fcntl.h>#include <string.h>int main(int argc,char* argv[]){void* buf = NULL;if(( buf = mmap(NULL,BUFSIZ,PROT_WRITE|PROT_READ,MAP_SHARED|MAP_ANON,-1,0)) == MAP_FAILED){perror("mmap error\n");return 1;}if(fork()){strcpy(buf,argv[1]);}else{printf("%s\n",buf);}munmap(buf,BUFSIZ);}
- POSIX共享内存(内存映射)
- 【IPC】Posix共享内存区与mmap内存映射
- 共享内存(内存映射)
- Posix多线程-共享内存
- posix 基于共享内存
- posix 共享内存
- POSIX 共享内存
- Posix共享内存区
- POSIX共享内存
- 关于Posix共享内存
- Posix共享内存区
- 内存映射,共享内存
- IPC通信:Posix共享内存
- Posix共享内存区基础知识
- Linux下:POSIX内存对象映射+POSIX内存对象信号量
- CreateFileMapping映射共享内存
- mmap 共享 内存映射
- 共享内存映射
- 史上最全的常用开发工具类收集(持续更新中)
- RSA加密算法加密与解密过程解析
- 关于error: command 'gcc' failed with exit status 1错误的解决方法的一些总结
- Redux入门
- const的用法,特别是用在函数前面与后面的区别!
- POSIX共享内存(内存映射)
- 进程通信
- mysql更新两个表 使用一个关联字段
- 两种高性能I/O设计模式(Reactor/Proactor)的比较
- POJ 1366 Word 笔记
- 8K视频质量技术测试,8K视频知识介绍
- CUDA(33)之ETH Mining(Parallel-mining project based on Opencl/GPU )
- 统计工程代码行数
- 配置虚拟机局域网内可达,可上网(centos6.5)