在读apue的时候,共享存储区的讲解并没用实例,为此自己写了一个小程序,程序粗创建子进程,由子进程从终端接收字符串存入共享区,转载请尊重原创、保留相关链接本文来自多宝平台:http://www.mbodb.com
父进程从共享区读出字符串并输出。同时,父子进程均输出各自的共享区的地址区间 区间。
运行结果:
分析:共结果可发现,父子进程的共享区区间地址相同,根据apue的说明,此处可能使用了“匿名存储映射 ”技术,但是不能认为共享存储区在不同的进程中地址都相同,这 仅是在父子进程中。在不同进程中,可能将共享区
连接到不同的地址,所以当在共享区中存入指针类型时,绝不会存放实际物理地址,相反,多宝指针值设置为段内另一对象的偏移量,偏移量为所指对象的实际地址减去共享存储区的起始地址。
另外:通过执行ipcs命令可以发现,当程序结束后,共享存储区依然还在
父进程从共享区读出字符串并输出。同时,父子进程均输出各自的共享区的地址区间 区间。
点击(此处)折叠或打开
- #include "apue.h"
- #include <sys/shm.h>
- #define SHM_SIZE 100000//共享存储区长度
- #define SHM_MODE 0600//共享存储区默认访问权限
- int
- main(void)
- {
- int shmid,pid;
- char* shmptr;
- key_t key;
- if(key=ftok("sharem.c",1)==-1) //使用ftok创建相应的key
- printf("ftok error\n");
- if((shmid=shmget(key,SHM_SIZE,IPC_CREAT|SHM_MODE))==-1)
- printf("shmget error\n");
- if((pid=fork())<0)
- printf("fork error\n");
- else if(pid==0)//子进程,从终端接收字符串存入共享存储区
- {
- if((shmptr=shmat(shmid,0,0))==(void*)-1)
- printf("child shmat error\n");
- printf("child share memory attached from %lx to %lx\n",(unsigned long)shmptr,(unsigned long)shmptr+SHM_SIZE);//输出共享存储区在子进程中的地址区间
- printf("child input:");
- scanf("%s",shmptr);
- exit(0);
- }
- else//父进程,从共享存储区读出字符串输出到终端
- {
- sleep(5);
- if((shmptr=shmat(shmid,0,0))==(void*)-1)
- printf("parent shmat error\n");
- printf("parent share memory attached from %lx to %lx\n",(unsigned long)shmptr,(unsigned long)shmptr+SHM_SIZE);//输出共享存储区在父进程中的地址区间
- printf("parent output:");
- printf("%s\n",shmptr);
- }
- exit(0);
- }
- //注:本程序为了是程序简洁,并没有采用信号量或者记录锁来保证共享区的同步访问,而是采用让父进程等待5秒钟来保证子进程先执行。
分析:共结果可发现,父子进程的共享区区间地址相同,根据apue的说明,此处可能使用了“匿名存储映射 ”技术,但是不能认为共享存储区在不同的进程中地址都相同,这 仅是在父子进程中。在不同进程中,可能将共享区
连接到不同的地址,所以当在共享区中存入指针类型时,绝不会存放实际物理地址,相反,多宝指针值设置为段内另一对象的偏移量,偏移量为所指对象的实际地址减去共享存储区的起始地址。
另外:通过执行ipcs命令可以发现,当程序结束后,共享存储区依然还在