共享内存的创建和映射shmget()和shmat()

来源:互联网 发布:网络推广经理工作职责 编辑:程序博客网 时间:2024/05/22 14:22

comments:record 这里面的sharemory 更主要是字符串比较和copy。总不用这个看了2遍才看懂。


共享内存的实现分为两步:

1、创建共享内存,用到的函数是shmget();

2、映射共享内存,就是把这段创建的共享内存映射到具体的进程空间去,使用的函数是:shmat();

这样就可以使用不带缓冲的I/O读写命令对其进行操作了。

实例如下:

[cpp] view plaincopy
  1. /* 
  2.  * shmem.c 
  3.  * 
  4.  *  Created on: 2012-7-20 
  5.  *      Author: liwei.cai 
  6.  */  
  7. /** 
  8.  * 该实例说明:如何使用基本的共享内存函数。 
  9.  * 功能:首先创建一个共享内存区,之后创建子进程,在父子进程中将共享内存 
  10.  * 分别映射到各自的进程地址空间中。 
  11.  *  父进程先等待用户输入,然后将用户输入的字符串写入到共享内存,之 
  12.  * 后往共享内存的头部写入“WROTE”字符串表示父进程已成功写入数据。子进程 
  13.  * 一直等待共享内存的头部字符串是“WROTE”,然后将共享内存的有效数据打印 
  14.  * 出来,之后父子进程分别解除与共享内存的映射。 
  15.  *  最后在子进程中删除共享内存。 
  16.  */  
  17. #include <sys/types.h>  
  18. #include <sys/ipc.h>  
  19. #include <sys/shm.h>  
  20. #include <stdio.h>  
  21. #include <stdlib.h>  
  22. #include <string.h>  
  23.   
  24. #define BUFFER_SIZE 2048  
  25.   
  26. int main()  
  27. {  
  28.     pid_t pid;  
  29.     int shmid;  
  30.     char *shm_addr;  
  31.     char flag[] = "WROTE";  
  32.     char *buff;  
  33.   
  34.     //创建共享内存  
  35.     if ((shmid = shmget(IPC_PRIVATE, BUFFER_SIZE, 0666)) < 0)  
  36.     {  
  37.         perror("shmget");  
  38.         exit(1);  
  39.     }  
  40.     else  
  41.     {  
  42.         printf("Create shared-memory: %d\n", shmid);  
  43.     }  
  44.   
  45.     //显示共享内存的情况  
  46.     system("ipcs -m");  
  47.   
  48.     pid = fork();  
  49.     if (pid == -1)  
  50.     {  
  51.         perror("fork");  
  52.         exit(1);  
  53.     }  
  54.     else if (pid == 0) //子进程  
  55.     {  
  56.         // 映射共享内存  
  57.         if ((shm_addr = shmat(shmid, 0, 0)) == (void*)-1)  
  58.         {  
  59.             perror("Child: shmat");  
  60.             exit(1);  
  61.         }  
  62.         else  
  63.         {  
  64.             printf("Child:Attach shared-memory: %p\n", shm_addr);  
  65.         }  
  66.         system("ipcs -m");  
  67.   
  68.         //通过检查在共享内存的头部是否标志字符串“WROTE”来确认  
  69.         //父进程已经此案够共享内存写入有效数据  
  70.         while(strncmp(shm_addr, flag, strlen(flag)))  
  71.         {  
  72.             printf("Child: wait for enable data...\n");  
  73.             sleep(5);  
  74.         }  
  75.         //获取共享内存的有效数据并显示  
  76.         strcpy(buff, shm_addr + strlen(flag));  
  77.         printf("Child: Shared-memory: %s\n", buff);  
  78.   
  79.         //解除共享内存映射  
  80.         if((shmdt(shm_addr)) < 0)  
  81.         {  
  82.             perror("shmdt");  
  83.             exit(1);  
  84.         }  
  85.         else  
  86.         {  
  87.             printf("Child: Deattach shared-memory\n");  
  88.         }  
  89.         system("ipcs -m");  
  90.   
  91.         //删除共享内存  
  92.         if(shmctl(shmid, IPC_RMID, NULL) == -1)  
  93.         {  
  94.             perror("Child: shmctl(IPC_RMID)\n");  
  95.             exit(1);  
  96.         }  
  97.         else  
  98.         {  
  99.             printf("Delete shared-memory\n");  
  100.         }  
  101.         system("ipcs -m");  
  102.     }  
  103.     else    //父进程  
  104.     {  
  105.         //映射共享内存  
  106.         if ((shm_addr = shmat(shmid, 0, 0)) == (void*)-1)  
  107.         {  
  108.             perror("Parent: shmat");  
  109.             exit(1);  
  110.         }  
  111.         else  
  112.         {  
  113.             printf("Parent:Attach shared-memory: %p\n", shm_addr);  
  114.         }  
  115.         sleep(1);  
  116.         printf("\n Input some string: \n");  
  117.         fgets(buff, BUFFER_SIZE,stdin);  
  118.         strncpy(shm_addr + strlen(flag), buff, strlen(buff));  
  119.         strncpy(shm_addr, flag, strlen(flag));  
  120.   
  121.         //解除共享内存映射  
  122.         if((shmdt(shm_addr)) < 0)  
  123.         {  
  124.             perror("shmdt");  
  125.             exit(1);  
  126.         }  
  127.         else  
  128.         {  
  129.             printf("Parent: Deattach shared-memory\n");  
  130.         }  
  131.         system("ipcs -m");  
  132.   
  133.         waitpid(pid, NULL, 0);  
  134.         printf("Finished\n");  
  135.     }  
  136.     exit(0);  
  137. }  

运行调试的时候出现,堆栈错误,请读者仔细阅读和修改代码,找出错误,附在下面。


http://blog.csdn.net/cailiwei712/article/details/7766831

0 0
原创粉丝点击