【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 共享内存
来源:互联网 发布:卓鸿网络 编辑:程序博客网 时间:2024/06/05 09:15
【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 共享内存
共享内存IPC原理
共享内存进程间通信机制主要用于实现进程间大量的数据传输。
共享内存是在内存中单独开辟一段内存空间,这段内存空间有自己特有的数据结构,包括访问权限、大小和最近访问时间等信息。该数据结构定义如下:
在使用共享内存进行数据存取是,有必要使用二元信号量来同步两个进程,以实现对共享内存的写操作。
共享内存与管道的对比
Linux共享内存管理
1. 创建共享内存
2. 共享内存控制
3. 映射共享内存
int shmat(int shmid,char *shmaddr,int flag)
参数:
shmid:shmget函数返回的共享存储标识符
flag:决定以什么样的方式来确定映射的地址(通常为0)
返回值:
如果成功,则返回共享内存映射到进程中的地址;如果失败,则返回-1。
4. 分离共享内存对象的映射
当一个进程不再需要共享内存时,需要把它从进程地址空间中多里。int shmdt(char *shmaddr)
共享内存的权限管理示例
#include<sys/shm.h>#include<unistd.h>#include<stdlib.h>#include<stdio.h>#include<sys/ipc.h>#include<string.h>int main(int argc,char *argv[]){key_t key;int shm_id;char *ptr;key=ftok("/",10);shm_id=shmget(key,100,IPC_CREAT|SHM_R);printf("get the shm id is %d\n",shm_id);if ((ptr = (char *)shmat(shm_id, NULL, SHM_RDONLY)) == NULL){if (shmctl(shm_id, IPC_RMID, NULL) == -1)perror("Failed to remove memory segment");exit(EXIT_FAILURE);}printf("in yangzd the attach add is %p\n",ptr);printf("*ptr=%c\n",*ptr);printf("now ,try to write the memory\n");*ptr='d';printf("*ptr=%c\n",*ptr);shmdt(ptr);shmctl(shm_id,IPC_RMID,0);}运行结果(因为是SHM_RDONLY,所以普通用户不能进行写操作,会出现段错误):
$ ./shmat_rd_flag_regular get the shm id is 32769in yangzd the attach add is 0xb7769000*ptr=now ,try to write the memory段错误 (核心已转储)
共享内存处理应用示例
发送端:
#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/shm.h>#include <sys/ipc.h>#include <sys/sem.h>#include <string.h>int main(int argc,char *argv[]){int running=1;int shid;int semid;int value;void *sharem=NULL;struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_flg = SEM_UNDO;if((semid=semget((key_t)123456,1,0666|IPC_CREAT))==-1){perror("semget");exit(EXIT_FAILURE);}if (semctl(semid, 0, SETVAL, 0) == -1){printf("sem init error"); if(semctl(semid,0,IPC_RMID,0)!=0){perror("semctl");exit(EXIT_FAILURE);}exit(EXIT_FAILURE);}shid=shmget((key_t)654321,(size_t)2048,0600|IPC_CREAT);if(shid==-1){perror("shmget");exit(EXIT_FAILURE);}sharem=shmat(shid,NULL,0);if(sharem==NULL){perror("shmat");exit(EXIT_FAILURE);}while(running){if((value=semctl( semid, 0, GETVAL ))==0){printf("write data operate\n");printf("please input something:");scanf("%s",sharem);sem_b.sem_op = 1;if (semop(semid, &sem_b, 1) == -1) {fprintf(stderr, "semaphore_p failed\n");exit(EXIT_FAILURE);}}if(strcmp(sharem,"end")==0)running--;}shmdt(sharem);return 0;}接收端:
#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <unistd.h>#include <string.h>#include <sys/ipc.h>#include <sys/shm.h>#include <sys/sem.h>int main(int argc,char *argv[]){int running=1;char *shm_p=NULL;int shmid;int semid;int value;struct sembuf sem_b;sem_b.sem_num = 0;sem_b.sem_flg = SEM_UNDO;if((semid=semget((key_t)123456,1,0666|IPC_CREAT))==-1){perror("semget");exit(EXIT_FAILURE);}shmid=shmget((key_t)654321,(size_t)2048,0600|IPC_CREAT);if(shmid==-1){perror("shmget");exit(EXIT_FAILURE);}shm_p=shmat(shmid,NULL,0);if(shm_p==NULL){perror("shmat");exit(EXIT_FAILURE);}while(running){if((value=semctl( semid, 0, GETVAL ))==1){printf("read data operate\n");sem_b.sem_op = -1;if (semop(semid, &sem_b, 1) == -1) {fprintf(stderr, "semaphore_p failed\n");exit(EXIT_FAILURE);}printf("%s\n",shm_p);}if(strcmp(shm_p,"end")==0)running--;}shmdt(shm_p);if(shmctl(shmid,IPC_RMID,0)!=0){perror("shmctl");exit(EXIT_FAILURE);}if(semctl(semid,0,IPC_RMID,0)!=0){perror("semctl");exit(EXIT_FAILURE);}return 0;}发送端运行结果:
$ ./shm_sem_example_send write data operateplease input something:hellowrite data operateplease input something:worldwrite data operateplease input something:end接收端运行结果:
$ ./shm_sem_example_recv read data operatehelloread data operateworld
运行过程中在另一终端中用“ipcs”命令可以查看使用的共享内存和信号量信息
$ ipcs------------ 共享内存段 --------------键 shmid 拥有者 权限 字节 nattch 状态 0x00000000 0 yang 600 393216 2 目标 0x0a010002 32769 yang 400 100 0 0x0009fbf1 98306 yang 600 2048 2 --------- 信号量数组 -----------键 semid 拥有者 权限 nsems 0x0001e240 32768 yang 666 1 --------- 消息队列 -----------键 msqid 拥有者 权限 已用字节数 消息
原文链接:
http://blog.csdn.net/geng823/article/details/41147911
0 0
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 共享内存
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 孤儿进程和僵死进程
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 进程资源及属性
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 回收进程用户/内核资源
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 守护进程
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信基础
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - Linux常见信号及处理
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 安装信号与捕捉信号
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号集与屏蔽信号
- 【原创】《Linux高级程序设计》杨宗德著- 进程管理与程序开发 - fork和vfork函数
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - exec和system函数
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 管道
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 等待信号
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号应用实例
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 信号量通信机制
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - System V进程间通信之消息队列
- 【原创】《Linux高级程序设计》(杨宗德著)--- Linux进程存储管理
- watchmen linux高级程序设计 02进程内存管理
- 保存图片到系统相册
- Parade - UVa 1427 dp+优先队列
- PHP foreach
- 第十二周项目-阅读程序7
- Week Part2:2014/11/9
- 【原创】《Linux高级程序设计》杨宗德著 - 进程管理与程序开发 - 共享内存
- iOS学习之一 ---------值得学习的博文[更新日期:2015/03/08]
- 深入理解PHP中的opcache原理
- 《黑客与画家》读后感
- 日语と的用法
- 【测绘】高速公路中线放样
- 功课数学分析(一) 第一讲
- 第十二周项目-阅读程序
- jQuery获取Select选择的Text和Value