进程通信系列(13)共享内存系统调用与代码示例
来源:互联网 发布:万网和阿里云什么关系 编辑:程序博客网 时间:2024/06/05 19:16
1.创建共享内存对象函数
3.共享内存映射
4.解除映射
1)函数原型
#include <sys/shm.h>int shmget(key_t key, size_t size, int shmflg);
返回值: 如果成功,返回共享内存段标识符。如果失败,则返回-1。
key:用户指定的共享内存键值,一般可以设置为IPC_PRIVATE(0)size:共享内存大小
shmflg: IPC_CREAT, IPC_EXCL等权限组合2)errno
EINVAL (无效的内存段大小)EEXIST (内存段已经存在,无法创建)
EIDRM (内存段已经被删除)
ENOENT (内存段不存在)EACCES (权限不够)
ENOMEM (没有足够的内存来创建内存段)
2、共享内存对象的控制操作
1)函数原型#include <sys/shm.h>
int shmctl(int shmid, int cmd, struct shmid_ds *buf);返回: 成功返回0、出错返回-1
2)参数shmid:共享内存ID
buf:共享内存属性指针cmd参数取值:
IPC_STAT 获取共享内存段属性IPC_SET 设置共享内存段属性
IPC_RMID 删除共享内存段SHM_LOCk 锁定共享内存段页面(页面映射到物理内存不和外存进行换入换出操作)
SHM_ULOCK 解除共享内存段页面的锁定3.共享内存映射
1) 函数原型
#include <sys/shm.h>void* shmat(int shmid, char *shmaddr, int shmflg);
返回: 成功返回共享内存段连接到进程中的地址,失败返回-12) 参数
shmid:共享内存IDshmaddr:映射到进程虚拟内存空间的地址,建议设置为0,由操作系统分配。
shmflag:若shmaddr设置为0,则shmflag也设置为0.SHM_RND
SHMLBA 地址为2的乘方SHM_RDONLY 只读方式链接
3)errno
EINVAL (无效的IPC ID 值或者无效的地址)ENOMEM (没有足够的内存)
EACCES (存取权限不够)
4.解除映射
int shmdt(char* shmaddr);
返回:如果失败,则返回-1参数:
shmaddr:为shmat返回的地址
示例代码:
父进程创建一个子进程,然后父进程向共享内存中写入数据,子进程读取共享内存中的数据。为了保证父进程首先写入数据,其后子进程进行读取这种互斥机制,引入了管道机制,子进程通过等待管道中的数据,将自己阻塞,父进程向共享内存中写入数据后,向管道写入一个字节,触发子进程阻塞结束,从而子进程去读共享内存中数据。
tell.h#ifndef __TELL_H__#define __TELL_H__extern void init();extern void wait_pipe();extern void notify_pipe();extern void destroy_pipe();#endiftell.c#include <stio.h>#include <stdlib.h>#include <string.h>#include "tell.h"static int fd[2];void init(){ if(pipe(fd) < 0) { perror("pipe error"); }}void wait_pipe(){ char c; if(read(fd[0], &c, 1) < 0) { perror("wait pipe error"); }}void notify_pipe(){ char c = 'c'; if(write(fd[1], &c, 1) !+ 1) { perror("notify pipe error"); }}void destroy_pipe(){ close(fd[0]); close(fd[1]);}cal_shm.c#include <sys/shm.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include "tell.h"int main(){ int shmid; if((shmid = shmget(IPC_PRIVATE, 1024, IPC_CREAT|IPC_EXCL|0777)) < 0) { perror("shmget error"); exit(1); } pid_t pid; init();//初始化管道 if((pid = fork()) < 0) { perror("fork error"); exit(0); } else if(pid > 0) { //进行共享内存映射 int *pi = (int *)shmat(shmid, 0, 0); if(pi == (int*)(-1)) { perror("shmat error"); exit(1); } //往共享内存中写入数据(通过操作映射的地址即可) *pi = 100; *(pi + 1) = 200; //操作完毕解除共享内存的映射 shmdt(pi); //通知子进程读取数据 notify_pipe(); destory_pipe(); wait(0); } else {//子进程 wait_pipe(); //子进程去从共享内存中读取数据 //子进程进行共享内存的映射 int *pi = (int*)shmat(shmid, 0, 0); if(pi == (int*)(-1)) { perror("shmat error"); exit(1); } print("start: %d, end: %d\n", *pi, *(pi +1)); //读取完毕后解除映射 shmdt(pi); //删除共享内存 shmctl(shmid, IPC_RMID, NULL); destory_pipe(); } return 0;}
阅读全文
0 0
- 进程通信系列(13)共享内存系统调用与代码示例
- linux进程通信(一)--共享内存+信号量,代码示例
- linux进程通信(一)--共享内存+信号量,代码示例
- linux进程通信(一)--共享内存+信号量,代码示例
- 进程通信系列-共享内存
- linux进程共享内存通信示例
- Linux环境进程间通信系列(五):共享内存
- Linux环境进程间通信系列(五):共享内存
- 进程间通信系列(12)共享内存的基本概念
- 进程通信(共享内存)
- 共享内存(进程通信)
- 撸代码--linux进程通信(基于共享内存)
- 进程间通信:共享内存(代码实现)
- Linux进程通信---共享内存 代码实现
- Linux系统下-进程间通信(共享内存-详解)
- 系统编程之进程通信 共享内存
- linux进程同步与通信(共享内存和信号量)
- 进程通信之共享内存与信号量
- C++加减随机计算
- 使用Node.JS监听文件夹变化
- Sublime Text 3 安装javascript控制台环境(Bulid System)
- Android基于MVP框架的联网登陆软件
- erlang复杂链表查找
- 进程通信系列(13)共享内存系统调用与代码示例
- nginx多个if里面proxy_pass
- jquery无法为动态生成的元素添加点击事件的解决方法
- CSS动画的性能优化
- 基于范围的for循环 调试失败 提示应输入
- 模拟微信联系人右侧字母滑动
- (2)Linux的基本概念
- jqgrid单元格里面内容过长自动截取带省略号
- Hive源码导入eclipse——细读Hive源码(一)