Chinaunix首页 | 论坛 | 博客
  • 博客访问: 524419
  • 博文数量: 86
  • 博客积分: 1076
  • 博客等级: 准尉
  • 技术积分: 1018
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-02 19:15
文章分类

全部博文(86)

文章存档

2013年(15)

2012年(69)

2011年(2)

分类: LINUX

2012-04-01 13:19:11

    为了在多个进程间交换数据,内核专门留出了一块共享内存区域,所有需要访问该共享区域的进程都要把这共享区域映射到本进程的地址空间中。每个内存区域都有一个标示符(shmid),进程可以通过这个标示符访问内存区域。
    共享内存通过shmget()获得或创建一个IPC共享内存区域,并返回相应的标示符。然后调用系统调用shmat()完成将该共享内存区域映射到进程地址空间。
1、函数接口

参考:http://blog.chinaunix.net/uid-25272011-id-3157708.html

2、给出实例以及运行结果:
write.c

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/ipc.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5. #include <stdlib.h>
  6. #include <sys/shm.h>
  7. #include <string.h>

  8. #define MEM_SIZE 4096

  9. //首先创建共享内存,并写入数据:(将struct People data[4]中的数据写入创建的共享内存)
  10. //编译运行后,可用Shell命令ipcs -m查看,删除可用ipcrm -m (shmid号)

  11. struct People{
  12.     char name[20];
  13.     char age;
  14. };

  15. int main()
  16. {
  17.     int i;
  18.     key_t key;
  19.     char *pathname="./ftok.txt";
  20.     int proj_id=5;
  21.     int shm_id;
  22.     struct People *shm_addr;
  23.     struct People data[4]={
  24.         {"name1",21},{"name2",22},{"name3",23},{"name4",24}
  25.     };

  26.     if ((key=ftok(pathname,proj_id))==-1){
  27.         perror("ftok");
  28.         exit(-1);
  29.     }
  30.     else{
  31.         printf("ftok success! key=%d\n",key);
  32.     }

  33.     if((shm_id=shmget(key,MEM_SIZE,IPC_EXCL|IPC_CREAT|0600))==-1){
  34.         perror("shmget");
  35.         exit(-1);
  36.     }
  37.     else{
  38.         printf("shmget success! shm_id=%d\n",shm_id);
  39.     }

  40.     if((shm_addr=shmat(shm_id,0,0))==(void *)-1){
  41.         perror("shmat");
  42.         exit(-1);
  43.     }
  44.     else{
  45.         printf("shmat success!shm_addr=%p\n",shm_addr);
  46.     }

  47.     printf("start copy data to memory\n");
  48.     memcpy((void *)shm_addr,(void *)data,sizeof(data));
  49.     printf("copy over\n");

  50.     for(i=0;i<4;i++){
  51.         printf("name:%s\t",shm_addr[i].name);
  52.         printf("age=%d\n",shm_addr[i].age);
  53.     }
  54.     if(shmdt(shm_addr)==-1){
  55.         perror("shmdt");
  56.         exit(-1);
  57.     }
  58.     else{
  59.         printf("shmdt success!\n");
  60.     }

  61.     return 0;
  62. }

read.c

点击(此处)折叠或打开

  1. #include <sys/types.h>
  2. #include <sys/ipc.h>
  3. #include <stdio.h>
  4. #include <errno.h>
  5. #include <stdlib.h>
  6. #include <sys/shm.h>
  7. #include <string.h>

  8. #define MEM_SIZE 4096

  9. //读出共享内存中的数据,并接删除共享内存:
  10. //编译运行后,再次用Shell命令ipcs -m查看,就没有创建的共享内存了。

  11. struct People{
  12.     char name[20];
  13.     char age;
  14. };

  15. int main()
  16. {
  17.     int i;
  18.     key_t key;
  19.     char *pathname="./ftok.txt";
  20.     int proj_id=5;
  21.     int shm_id;
  22.     struct People *shm_addr;

  23.     if ((key=ftok(pathname,proj_id))==-1){
  24.         perror("ftok");
  25.         exit(-1);
  26.     }
  27.     else{
  28.         printf("ftok success! key=%d\n",key);
  29.     }

  30.     if((shm_id=shmget(key,MEM_SIZE,0600))==-1){
  31.         perror("shmget");
  32.         exit(-1);
  33.     }
  34.     else{
  35.         printf("shmget success! shm_id=%d\n",shm_id);
  36.     }

  37.     if((shm_addr=shmat(shm_id,0,0))==(void *)-1){
  38.         perror("shmat");
  39.         exit(-1);
  40.     }
  41.     else{
  42.         printf("shmat success!shm_addr=%p\n",shm_addr);
  43.     }

  44.     for(i=0;i<4;i++){
  45.         printf("name:%s\t",shm_addr[i].name);
  46.         printf("age=%d\n",shm_addr[i].age);
  47.     }
  48.     if(shmdt(shm_addr)==-1){
  49.         perror("shmdt");
  50.         exit(-1);
  51.     }
  52.     else{
  53.         printf("shmdt success!\n");
  54.     }

  55.     if(shmctl(shm_id,IPC_RMID,0)==-1){        //这边才是删除那块共享缓冲区
  56.         perror("shmctl");
  57.         exit(-1);
  58.     }
  59.     else{
  60.         printf("shmctl success!\n");
  61.     }

  62.     return 0;
  63. }

详细的运行结果:

点击(此处)折叠或打开

  1. root@jgf:~/JGF/study/shm# ipcs -h
  2. ipcs provides information on ipc facilities for which you have read access.
  3. Resource Specification:
  4. -m : shared_mem
  5. -q : messages
  6. -s : semaphores
  7. -a : all (default)
  8. Output Format:
  9. -t : time
  10. -p : pid
  11. -c : creator
  12. -l : limits
  13. -u : summary
  14. -i id [-s -q -m] : details on resource identified by id
  15. usage : ipcs -asmq -tclup
  16. ipcs [-s -m -q] -i id
  17. ipcs -h for help.
  18. root@jgf:~/JGF/study/shm#
  19. root@jgf:~/JGF/study/shm# ipcs -m           //先打出系统当前的IPC

  20. ------ Shared Memory Segments --------
  21. key shmid owner perms bytes nattch status
  22. 0x00000000 65536 root 600 393216 2 dest
  23. 0x00000000 98305 root 600 393216 2 dest
  24. 0x00000000 131074 root 600 393216 2 dest
  25. 0x00000000 5046275 root 600 393216 2 dest
  26. 0x00000000 196612 root 600 393216 2 dest
  27. 0x00000000 229381 root 600 393216 2 dest
  28. 0x00000000 262150 root 600 393216 2 dest
  29. 0x00000000 294919 root 600 393216 2 dest
  30. 0x00000000 5079048 root 600 393216 2 dest
  31. 0x00000000 9568267 root 600 393216 2 dest
  32. 0x00000000 4292620 root 600 393216 2 dest
  33. 0x0056a4d5 10846221 root 660 488 0
  34. 0x0056a4d6 10878990 root 660 131072 0

  35. root@jgf:~/JGF/study/shm# ipcs -q

  36. ------ Message Queues --------
  37. key msqid owner perms used-bytes messages

  38. root@jgf:~/JGF/study/shm#
  39. root@jgf:~/JGF/study/shm#
  40. root@jgf:~/JGF/study/shm#
  41. root@jgf:~/JGF/study/shm# ipcs -s

  42. ------ Semaphore Arrays --------
  43. key semid owner perms nsems
  44. 0x0056a4d5 589824 root 660 1

  45. root@jgf:~/JGF/study/shm# ./write                //运行
  46. ftok: No such file or directory
  47. root@jgf:~/JGF/study/shm#
  48. root@jgf:~/JGF/study/shm#
  49. root@jgf:~/JGF/study/shm#
  50. root@jgf:~/JGF/study/shm# touch ftok.txt
  51. root@jgf:~/JGF/study/shm#
  52. root@jgf:~/JGF/study/shm#
  53. root@jgf:~/JGF/study/shm#
  54. root@jgf:~/JGF/study/shm# ./write
  55. ftok success! key=83989182
  56. shmget success! shm_id=13369353                  //创建了一块共享内存,返回ID号
  57. shmat success!shm_addr=0xb7769000
  58. start copy data to memory
  59. copy over
  60. name:name1 age=21
  61. name:name2 age=22
  62. name:name3 age=23
  63. name:name4 age=24
  64. shmdt success!
  65. root@jgf:~/JGF/study/shm# ipcs -m

  66. ------ Shared Memory Segments --------
  67. key shmid owner perms bytes nattch status
  68. 0x00000000 65536 root 600 393216 2 dest
  69. 0x00000000 98305 root 600 393216 2 dest
  70. 0x00000000 131074 root 600 393216 2 dest
  71. 0x00000000 5046275 root 600 393216 2 dest
  72. 0x00000000 196612 root 600 393216 2 dest
  73. 0x00000000 229381 root 600 393216 2 dest
  74. 0x00000000 262150 root 600 393216 2 dest
  75. 0x00000000 294919 root 600 393216 2 dest
  76. 0x00000000 5079048 root 600 393216 2 dest
  77. 0x050192be 13369353 root 600 4096 0              //在这里
  78. 0x00000000 9568267 root 600 393216 2 dest
  79. 0x00000000 4292620 root 600 393216 2 dest
  80. 0x0056a4d5 10846221 root 660 488 0
  81. 0x0056a4d6 10878990 root 660 131072 0

  82. root@jgf:~/JGF/study/shm# ./read
  83. ftok success! key=83989182
  84. shmget success! shm_id=13369353            //获取到了上面那块映射好的共享内存ID
  85. shmat success!shm_addr=0xb771b000
  86. name:name1 age=21
  87. name:name2 age=22
  88. name:name3 age=23
  89. name:name4 age=24
  90. shmdt success!
  91. shmctl success!
  92. root@jgf:~/JGF/study/shm# ipcs -m

  93. ------ Shared Memory Segments --------
  94. key shmid owner perms bytes nattch status
  95. 0x00000000 65536 root 600 393216 2 dest
  96. 0x00000000 98305 root 600 393216 2 dest
  97. 0x00000000 131074 root 600 393216 2 dest
  98. 0x00000000 5046275 root 600 393216 2 dest
  99. 0x00000000 196612 root 600 393216 2 dest
  100. 0x00000000 229381 root 600 393216 2 dest
  101. 0x00000000 262150 root 600 393216 2 dest
  102. 0x00000000 294919 root 600 393216 2 dest
  103. 0x00000000 5079048 root 600 393216 2 dest
  104. 0x00000000 9568267 root 600 393216 2 dest
  105. 0x00000000 4292620 root 600 393216 2 dest
  106. 0x0056a4d5 10846221 root 660 488 0
  107. 0x0056a4d6 10878990 root 660 131072 0
  108. --------------------------------------------------------------------------------
  109. --------------------------------------------------------------------------------
  110. root@jgf:~/JGF/study/shm# ./write       //重新运行
  111. ftok success! key=83989182              //键值相同
  112. shmget success! shm_id=13402121         //但ID不同了,应该是换了一块内存区域了
  113. shmat success!shm_addr=0xb77a3000
  114. start copy data to memory
  115. copy over
  116. name:name1 age=21
  117. name:name2 age=22
  118. name:name3 age=23
  119. name:name4 age=24
  120. shmdt success!
  121. root@jgf:~/JGF/study/shm#
  122. root@jgf:~/JGF/study/shm# ipcs -m

  123. ------ Shared Memory Segments --------
  124. key shmid owner perms bytes nattch status
  125. 0x00000000 65536 root 600 393216 2 dest
  126. 0x00000000 98305 root 600 393216 2 dest
  127. 0x00000000 131074 root 600 393216 2 dest
  128. 0x00000000 5046275 root 600 393216 2 dest
  129. 0x00000000 196612 root 600 393216 2 dest
  130. 0x00000000 229381 root 600 393216 2 dest
  131. 0x00000000 262150 root 600 393216 2 dest
  132. 0x00000000 294919 root 600 393216 2 dest
  133. 0x00000000 5079048 root 600 393216 2 dest
  134. 0x050192be 13402121 root 600 4096 0
  135. 0x00000000 9568267 root 600 393216 2 dest
  136. 0x00000000 4292620 root 600 393216 2 dest
  137. 0x0056a4d5 10846221 root 660 488 0
  138. 0x0056a4d6 10878990 root 660 131072 0

  139. root@jgf:~/JGF/study/shm#
  140. root@jgf:~/JGF/study/shm# ipcrm -h
  141. ipcrm: invalid option -- 'h'
  142. ipcrm: illegal option -- ?
  143. usage: ipcrm [ [-q msqid] [-m shmid] [-s semid]
  144. [-Q msgkey] [-M shmkey] [-S semkey] ... ]
  145. root@jgf:~/JGF/study/shm# ipcrm --h
  146. ipcrm: invalid option -- '-'
  147. ipcrm: illegal option -- ?
  148. usage: ipcrm [ [-q msqid] [-m shmid] [-s semid]
  149. [-Q msgkey] [-M shmkey] [-S semkey] ... ]
  150. root@jgf:~/JGF/study/shm# ipcrm -m 13402121    //删除该共享内存区
  151. root@jgf:~/JGF/study/shm#
  152. root@jgf:~/JGF/study/shm#
  153. root@jgf:~/JGF/study/shm#
  154. root@jgf:~/JGF/study/shm# ipcs -m

  155. ------ Shared Memory Segments --------
  156. key shmid owner perms bytes nattch status
  157. 0x00000000 65536 root 600 393216 2 dest
  158. 0x00000000 98305 root 600 393216 2 dest
  159. 0x00000000 131074 root 600 393216 2 dest
  160. 0x00000000 5046275 root 600 393216 2 dest
  161. 0x00000000 196612 root 600 393216 2 dest
  162. 0x00000000 229381 root 600 393216 2 dest
  163. 0x00000000 262150 root 600 393216 2 dest
  164. 0x00000000 294919 root 600 393216 2 dest
  165. 0x00000000 5079048 root 600 393216 2 dest
  166. 0x00000000 9568267 root 600 393216 2 dest
  167. 0x00000000 4292620 root 600 393216 2 dest
  168. 0x0056a4d5 10846221 root 660 488 0
  169. 0x0056a4d6 10878990 root 660 131072 0

  170. root@jgf:~/JGF/study/shm# ./read        //此时那块区域被删除掉了
  171. ftok success! key=83989182              //键值相同
  172. shmget: No such file or directory       //但是get不到那块区域了
  173. root@jgf:~/JGF/study/shm#
  174. root@jgf:~/JGF/study/shm#
  175. root@jgf:~/JGF/study/shm#

本文的源代码参考自:http://waiter94.blog.163.com/blog/static/5277376920100213456475/?fromdm&fromSearch&isFromSearchEngine=yes

阅读(1036) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~