Chinaunix首页 | 论坛 | 博客
  • 博客访问: 150452
  • 博文数量: 23
  • 博客积分: 546
  • 博客等级: 中士
  • 技术积分: 608
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-02 18:04
文章分类

全部博文(23)

文章存档

2012年(23)

我的朋友

分类: C/C++

2012-07-06 15:34:25

共享内存


最为高效的进程间通信方式
 
进程直接读写内存,不需要任何数据的拷贝
  •为了在多个进程间交换信息,内核专门留出了一块内存区
  •由需要访问的进程将其映射到自己私有地址空间
  •进程直接读写这一内存区而不需要进行数据的拷贝,提高了效率
 
多个进程共享一段内存,需要依靠某种同步机制,如互斥锁和信号量等

l共享内存编程步骤:
  1. 创建共享内存
    •函数shmget()
    •从内存中获得一段共享内存区域
 
  2. 映射共享内存
    •把这段创建的共享内存映射到具体的进程空间中
    •函数shmat()
 
  3. 使用这段共享内存
    •可以使用不带缓冲的I/O读写命令对其进行操作
 
  4. 撤销映射操作: 函数shmdt()
 
  5. 删除共享内存: 函数shctl()








 下面这个例子完成:父进程从stdin读取字符串并保存到共享内存中,子进程从共享内存中读出数据并输出到stdout


点击(此处)折叠或打开

  1. #include <stdio.h>
  2.  #include <stdlib.h>
  3.  #include <string.h>
  4.  #include <sys/types.h>
  5.  #include <sys/ipc.h>
  6.  #include <sys/shm.h>
  7.  
  8.  #define BUFFER_SIZE 2048
  9.  
  10.  int main() {
  11.      pid_t pid;
  12.      int shmid;
  13.      char *shm_addr;
  14.      char flag[]="Parent";
  15.      char buff[BUFFER_SIZE];
  16.  // 创建当前进程的私有共享内存
  17.      if ((shmid=shmget(IPC_PRIVATE,BUFFER_SIZE,0666))<0) {
  18.          perror("shmget");
  19.          exit(1);
  20.      } else
  21.          printf("Create shared memory: %d.\n",shmid);
  22.  
  23.  // ipcs 命令往标准输出写入一些关于活动进程间通信设施的信息
  24.  // -m 表示共享内存
  25.      printf("Created shared memory status:\n");
  26.      system("ipcs -m");
  27.  
  28.      if((pid=fork())<0) {
  29.          perror("fork");
  30.          exit(1);
  31.      }else if (pid==0) {
  32.  // 自动分配共享内存映射地址,为可读可写,映射地址返回给shm_addr
  33.          if ((shm_addr=shmat(shmid,0,0))==(void*)-1) {
  34.              perror("Child:shmat");
  35.              exit(1);
  36.          }else
  37.              printf("Child: Attach shared-memory: %p.\n",shm_addr);
  38.  
  39.          printf("Child Attach shared memory status:\n");
  40.          system("ipcs -m");
  41.  // 比较shm_addr,flag的长度为strlen(flag)的字符
  42.  // 当其内容相同时,返回0
  43.  // 否则返回(str1[n]-str2[n]
  44.          while (strncmp(shm_addr,flag,strlen(flag))) {
  45.              printf("Child: Waiting for data...\n");
  46.              sleep(10);
  47.          }
  48.  
  49.          strcpy(buff,shm_addr+strlen(flag));
  50.          printf("Child: Shared-memory: %s\n",buff);
  51.  // 删除子进程的共享内存映射地址
  52.          if (shmdt(shm_addr)<0) {
  53.              perror("Child:shmdt");
  54.              exit(1);
  55.          }else
  56.              printf("Child: Deattach shared-memory.\n");
  57.  
  58.          printf("Child Deattach shared memory status:\n");
  59.          system("ipcs -m");
  60.  
  61.      }else{
  62.          sleep(1);
  63.  // 自动分配共享内存映射地址,为可读可写,映射地址返回给shm_addr
  64.          if ((shm_addr=shmat(shmid,0,0))==(void*)-1) {
  65.              perror("Parent:shmat");
  66.              exit(1);
  67.          }else
  68.              printf("Parent: Attach shared-memory: %p.\n",shm_addr);
  69.  
  70.          printf("Parent Attach shared memory status:\n");
  71.          system("ipcs -m");
  72.  // shm_addr为flag+stdin
  73.          sleep(1);
  74.          printf("\nInput string:\n");
  75.          fgets(buff,BUFFER_SIZE-strlen(flag),stdin);
  76.          strncpy(shm_addr+strlen(flag),buff,strlen(buff));
  77.          strncpy(shm_addr,flag,strlen(flag));
  78.  // 删除父进程的共享内存映射地址
  79.          if (shmdt(shm_addr)<0) {
  80.              perror("Parent:shmdt");
  81.              exit(1);
  82.          }else
  83.              printf("Parent: Deattach shared-memory.\n");
  84.  
  85.          printf("Parent Deattach shared memory status:\n");
  86.          system("ipcs -m");
  87.  // 保证父进程在删除共享内存前,子进程能读到共享内存的内容
  88.          waitpid(pid,NULL,0);
  89.  // 删除共享内存
  90.          if (shmctl(shmid,IPC_RMID,NULL)==-1) {
  91.              perror("shmct:IPC_RMID");
  92.              exit(1);
  93.          }else
  94.              printf("Delete shared-memory.\n");
  95.  
  96.          printf("Child Delete shared memory status:\n");
  97.          system("ipcs -m");
  98.  
  99.          printf("Finished!\n");
  100.      }
  101.      
  102.      exit(0);
  103.  }
执行结果:

点击(此处)折叠或打开

  1. [tym@lxy procCOM]$ ./shareMemory
  2. create shared memory:491532
  3. create shared memory status:

  4. ------ Shared Memory Segments --------
  5. key shmid owner perms bytes nattch status
  6. 0x00000000 65536 tym 600 393216 2 dest
  7. 0x00000000 98305 tym 600 393216 2 dest
  8. 0x00000000 131074 tym 600 393216 2 dest
  9. 0x00000000 163843 tym 600 393216 2 dest
  10. 0x00000000 196612 tym 600 393216 2 dest
  11. 0x00000000 229381 tym 600 393216 2 dest
  12. 0x00000000 262150 tym 600 393216 2 dest
  13. 0x00000000 393223 tym 600 393216 2 dest
  14. 0x00000000 327688 tym 600 393216 2 dest
  15. 0x00000000 360457 tym 600 393216 2 dest
  16. 0x00000000 425994 tym 666 2048 0
  17. 0x00000000 458763 tym 666 2048 0
  18. 0x00000000 491532 tym 666 2048 0

  19. Child:Attach shared-memory:0xb7f99000.
  20. Attach shared memory status:

  21. ------ Shared Memory Segments --------
  22. key shmid owner perms bytes nattch status
  23. 0x00000000 65536 tym 600 393216 2 dest
  24. 0x00000000 98305 tym 600 393216 2 dest
  25. 0x00000000 131074 tym 600 393216 2 dest
  26. 0x00000000 163843 tym 600 393216 2 dest
  27. 0x00000000 196612 tym 600 393216 2 dest
  28. 0x00000000 229381 tym 600 393216 2 dest
  29. 0x00000000 262150 tym 600 393216 2 dest
  30. 0x00000000 393223 tym 600 393216 2 dest
  31. 0x00000000 327688 tym 600 393216 2 dest
  32. 0x00000000 360457 tym 600 393216 2 dest
  33. 0x00000000 425994 tym 666 2048 0
  34. 0x00000000 458763 tym 666 2048 0
  35. 0x00000000 491532 tym 666 2048 1

  36. child:waiting for data...
  37. Parent:Attach shared-memory:0xb7f99000.
  38. Parent Attach shared-memory status:

  39. ------ Shared Memory Segments --------
  40. key shmid owner perms bytes nattch status
  41. 0x00000000 65536 tym 600 393216 2 dest
  42. 0x00000000 98305 tym 600 393216 2 dest
  43. 0x00000000 131074 tym 600 393216 2 dest
  44. 0x00000000 163843 tym 600 393216 2 dest
  45. 0x00000000 196612 tym 600 393216 2 dest
  46. 0x00000000 229381 tym 600 393216 2 dest
  47. 0x00000000 262150 tym 600 393216 2 dest
  48. 0x00000000 393223 tym 600 393216 2 dest
  49. 0x00000000 327688 tym 600 393216 2 dest
  50. 0x00000000 360457 tym 600 393216 2 dest
  51. 0x00000000 425994 tym 666 2048 0
  52. 0x00000000 458763 tym 666 2048 0
  53. 0x00000000 491532 tym 666 2048 2


  54. Input string:
  55. hello
  56. Parent:Deattach shared-memory
  57. Parent Deattach shared-memory status:

  58. ------ Shared Memory Segments --------
  59. key shmid owner perms bytes nattch status
  60. 0x00000000 65536 tym 600 393216 2 dest
  61. 0x00000000 98305 tym 600 393216 2 dest
  62. 0x00000000 131074 tym 600 393216 2 dest
  63. 0x00000000 163843 tym 600 393216 2 dest
  64. 0x00000000 196612 tym 600 393216 2 dest
  65. 0x00000000 229381 tym 600 393216 2 dest
  66. 0x00000000 262150 tym 600 393216 2 dest
  67. 0x00000000 393223 tym 600 393216 2 dest
  68. 0x00000000 327688 tym 600 393216 2 dest
  69. 0x00000000 360457 tym 600 393216 2 dest
  70. 0x00000000 425994 tym 666 2048 0
  71. 0x00000000 458763 tym 666 2048 0
  72. 0x00000000 491532 tym 666 2048 1

  73. Child:shared-memory:hello

  74. Child Deattach shared memory status:

  75. ------ Shared Memory Segments --------
  76. key shmid owner perms bytes nattch status
  77. 0x00000000 65536 tym 600 393216 2 dest
  78. 0x00000000 98305 tym 600 393216 2 dest
  79. 0x00000000 131074 tym 600 393216 2 dest
  80. 0x00000000 163843 tym 600 393216 2 dest
  81. 0x00000000 196612 tym 600 393216 2 dest
  82. 0x00000000 229381 tym 600 393216 2 dest
  83. 0x00000000 262150 tym 600 393216 2 dest
  84. 0x00000000 393223 tym 600 393216 2 dest
  85. 0x00000000 327688 tym 600 393216 2 dest
  86. 0x00000000 360457 tym 600 393216 2 dest
  87. 0x00000000 425994 tym 666 2048 0
  88. 0x00000000 458763 tym 666 2048 0
  89. 0x00000000 491532 tym 666 2048 0

  90. Delete shared-memory.
  91. Child Delete shared memory status:

  92. ------ Shared Memory Segments --------
  93. key shmid owner perms bytes nattch status
  94. 0x00000000 65536 tym 600 393216 2 dest
  95. 0x00000000 98305 tym 600 393216 2 dest
  96. 0x00000000 131074 tym 600 393216 2 dest
  97. 0x00000000 163843 tym 600 393216 2 dest
  98. 0x00000000 196612 tym 600 393216 2 dest
  99. 0x00000000 229381 tym 600 393216 2 dest
  100. 0x00000000 262150 tym 600 393216 2 dest
  101. 0x00000000 393223 tym 600 393216 2 dest
  102. 0x00000000 327688 tym 600 393216 2 dest
  103. 0x00000000 360457 tym 600 393216 2 dest
  104. 0x00000000 425994 tym 666 2048 0
  105. 0x00000000 458763 tym 666 2048 0

  106. Finished

阅读(6821) | 评论(0) | 转发(4) |
0

上一篇:gdb的使用二

下一篇:linux单网卡上配置双IP

给主人留下些什么吧!~~