共享存储区通信实例及分析

来源:互联网 发布:windows7查看443端口 编辑:程序博客网 时间:2024/04/27 03:04
在读apue的时候,共享存储区的讲解并没用实例,为此自己写了一个小程序,程序粗创建子进程,由子进程从终端接收字符串存入共享区,转载请尊重原创、保留相关链接本文来自多宝平台http://www.mbodb.com
父进程从共享区读出字符串并输出。同时,父子进程均输出各自的共享区的地址区间区间。

点击(此处)折叠或打开

  1. #include "apue.h"
  2. #include <sys/shm.h>
  3. #define SHM_SIZE 100000//共享存储区长度
  4. #define SHM_MODE 0600//共享存储区默认访问权限
  5. int
  6. main(void)
  7. {
  8.   int shmid,pid;
  9.   char* shmptr;
  10.   key_t key;
  11.   if(key=ftok("sharem.c",1)==-1) //使用ftok创建相应的key
  12.     printf("ftok error\n");
  13.   if((shmid=shmget(key,SHM_SIZE,IPC_CREAT|SHM_MODE))==-1)
  14.     printf("shmget error\n");
  15.   if((pid=fork())<0)
  16.     printf("fork error\n");
  17.   else if(pid==0)//子进程,从终端接收字符串存入共享存储区
  18.   {
  19.     if((shmptr=shmat(shmid,0,0))==(void*)-1)
  20.         printf("child shmat error\n");
  21.     printf("child share memory attached from %lx to %lx\n",(unsigned long)shmptr,(unsigned long)shmptr+SHM_SIZE);//输出共享存储区在子进程中的地址区间
  22.        printf("child input:");
  23.     scanf("%s",shmptr);
  24.    exit(0);
  25.   }
  26.   else//父进程,从共享存储区读出字符串输出到终端
  27.   {
  28.     sleep(5);
  29.     if((shmptr=shmat(shmid,0,0))==(void*)-1)
  30.         printf("parent shmat error\n");
  31.     printf("parent share memory attached from %lx to %lx\n",(unsigned long)shmptr,(unsigned long)shmptr+SHM_SIZE);//输出共享存储区在父进程中的地址区间
  32.        printf("parent output:");
  33.     printf("%s\n",shmptr);
  34.   }
  35.   exit(0);
  36. }
  37. //注:本程序为了是程序简洁,并没有采用信号量或者记录锁来保证共享区的同步访问,多宝而是采用让父进程等待5秒钟来保证子进程先执行。
运行结果:

分析:共结果可发现,父子进程的共享区区间地址相同,根据apue的说明,此处可能使用了“匿名存储映射”技术,但是不能认为共享存储区在不同的进程中地址都相同,这仅是在父子进程中。在不同进程中,可能将共享区
连接到不同的地址,所以当在共享区中存入指针类型时,绝不会存放实际物理地址,相反,指针值设置为段内另一对象的偏移量,偏移量为所指对象的实际地址减去共享存储区的起始地址。
另外:通过执行ipcs命令可以发现,当程序结束后,共享存储区依然还在。
0 0