进程学习:进程间通信(system v IPC)2.共享内存
来源:互联网 发布:linux修改网卡配置 编辑:程序博客网 时间:2024/06/05 19:52
共享内存与消息队列、管道的区别:
1.消息队列、管道中的数据读取之后就没有了;而共享内存中的数据无论读取多少次,都还会在里面;
2.共享内存读取相对于消息队列与管道来说,效率最高,直接对指向共享内存的指针进行读写操作;
共享内存函数
共享内存函数
一、int shmget(key_t key, size_t size, int shmflg);
功能:创建或打开共享内存
参数:
key:键值;
size:要创建的共享内存的字节数;
shmflg:权限(IPC_CREAT | IPC_EXCL|0664)
返回值:
成功:返回shmid;
失败:返回 -1;
二、void *shmat(int shmid, const void *shmaddr, int shmflg);
功能:映射共享内存,即把指定的共享内存映射到进程的地址空间,用于访问;
参数:
shmid:要映射的共享内存的id号;
shmaddr:共享内存地址的选择方式:1.NULL,系统帮你选一块不碍事儿的地方;2.你自己选,一般不自己选;
shmflg:读写权限:1.SHM_RDONLY,即对共享内存只进行读操作;2.0,可读可写操作;
返回值:
成功:返回完成映射之后的共享内存地址;
失败:返回(void *)-1;
三、int shmdt(const void *shmaddr);
功能:解除当前进程与共享内存的映射关系;
参数:shmaddr:shmat的返回值,共享内存的地址;
返回值:
成功:0
失败:-1
四、int shmctl(int shmid, int cmd, struct shmid_ds *buf);
功能:对共享内存进行各种操作;
参数:
shmid:共享内存的id号;
cmd:命令:
IPC_STAT:获取shmid的属性信息,存放在第三个参数内;
IPC_SET:设置shmid的属性,要设置的属性放在第三个参数里;
IPC_RMID:删除共享内存,此时第三个参数为NULL;
返回值:
成功:0;
失败:-1;
编程实例:
下面我们来编写一个测试代码:从一个terminal输入到共享内存,另一个terminal从共享内存读取并输出打印;
在终端输入到共享内存:
#include "sem.h"int main(int argc, const char *argv[]){key_t key;int shmid;char *p = NULL;char buf[N];if( (key = ftok(".", 1)) < 0){perror("ftok error");exit(1);}if( (shmid = shmget(key, 512, IPC_CREAT|IPC_EXCL|0664)) < 0){if(errno == EEXIST){shmid = shmget(key, 512, 0664);puts("share buffer is exist");}else{perror("shmget error");exit(1);}}p = (char *)shmat(shmid, NULL, 0);if(p == (char *)-1){perror("shmat error");exit(1);}while(fgets(p, N, stdin) != NULL){if(strncmp(p, "quit", 4) == 0){break;}}shmdt(p);return 0;}
从共享内存读取数据并打印到终端:
#include "sem.h"int main(int argc, const char *argv[]){key_t key;int shmid;char *p = NULL;char buf[N];if( (key = ftok(".", 1)) < 0){perror("ftok error");exit(1);}if( (shmid = shmget(key, 512, IPC_CREAT|IPC_EXCL|0664)) < 0){if(errno == EEXIST){shmid = shmget(key, 512, 0664);puts("share buffer is exist");}else{perror("shmget error");exit(1);}}p = (char *)shmat(shmid, NULL, 0);if(p == (char *)-1){perror("shmat error");exit(1);}while(1){if(strncmp(p, "quit", 4) == 0){break;}fputs(p, stdout);}shmdt(p);shmctl(shmid, IPC_RMID, NULL);return 0;}
我们运行程序后发现,负责读取的终端会一直进行输出,刷屏了。这是因为共享内存里的数据不会因为对他进行了读取后就把里面的数据清空。
回想无名管道、有名管道、消息队列,都是读取后里面的东东就没有了。同时那三个是在内核空间进行的通信,这个不是在内核空间进行的通信;
要想实现一端输入,另一端读取(只读取一遍,不刷屏),我们还有结合信号灯的使用,让这个共享内存有个先后执行的顺序(也就是同步)。- 进程学习:进程间通信(system v IPC)2.共享内存
- Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存
- Linux C编程--进程间通信(IPC)5--System V IPC 机制3--共享内存
- System V进程间通信--共享内存
- Linux进程间通信(IPC)编程实践(七)共享内存的使用-System V共享内存(API)
- linux进程间通信之共享内存(system v)
- Linux进程间通信之共享内存(system v)
- 【九】 进程间通信——[System V IPC对象]共享内存(share memory)
- Linux程序设计学习笔记----System V进程通信(共享内存)
- 进程间通信(IPC):共享内存
- 进程间通信(IPC)---共享内存
- linux 进程间通信(system v 信号灯+system v 共享内存)实例
- 进程学习:进程间通信(system v IPC)1.消息队列
- 进程学习:进程间通信(system v IPC)3.信号灯
- 进程间通信(9) - 共享内存(System V)
- linux进程间通信-----System V共享内存总结实例
- 15章 进程间通信之共享内存区(Posix、System V共享内存)
- linux基础编程:进程通信之System V IPC:消息队列,信号量,共享内存
- TOP100summit:【分享实录-封宇】58到家多端消息整合之路
- 登陆注册
- 洛谷10月月赛R2-T3-Nephren Ruq Insania
- HOJ 2275 Number sequence(树状数组) 大于小于问题
- 8.通过和ServletAPI耦合的方式获取WEB资源
- 进程学习:进程间通信(system v IPC)2.共享内存
- 算法-二叉树查找排序
- 选择排序,冒泡排序及二分查找的代码实现
- Machine Learning学习之 系统(层次)聚类法
- Eclipse中安装STS(Spring Tool Suite)使用Spring Boot
- 今天开始写我的毕设
- 简单的SSH整合(基于注解和xml文件的配置)
- 使用eclipse作为python开发工具安装旧版pydev
- Java框架知识-笔记五