分享

C语言进程间通信(四)

 yggzs2002 2017-06-20

共享内存通信方式效率最高,毕竟是直接操作内存,但是要保证多个进程对同一块内存访问的同步互斥比较麻烦,借助信号量实现

对每个共享存储段,内核维护一个shmid_ds类型的结构体,定义在<sys/shm.h>文件中

C代码  收藏代码
  1. struct shmid_ds  
  2. {  
  3. struct ipc_perm shm_perm;   //共享内存的ipc_perm结构  
  4. size_t shm_segsz;   //共享内存区域大小,字节表示  
  5. pid_t shm_lpid; //最后一次调用shmop函数的进程ID  
  6. pid_t shm_cpid; //创建此共享内存的进程ID  
  7. unsigned short shm_lkcnt;   //共享内存被锁定的时间数  
  8. unsigned long shm_nattch;   //当前使用共享内存的进程数  
  9. time_t shm_atime;   //最后一次附加操作时间  
  10. time_t shm_dtime;   //最后一次分离操作时间  
  11. time_t shm_ctime;   //最后一次修改时间  
  12. }  

共享内存基本操作

1,创建或打开一个共享内存(shmget)

C代码  收藏代码
  1. //create_shm.c  
  2. #include<sys/types.h>  
  3. #include<sys/ipc.h>  
  4. #include<sys/shm.h>  
  5. #include<stdio.h>  
  6.   
  7. #define BUFSZ 1024  
  8.   
  9. int main()  
  10. {  
  11.         int shm_id;     //共享内存ID  
  12.         shm_id = shmget(IPC_PRIVATE,BUFSZ,0666);  
  13.         if(shm_id < 0){  
  14.                 printf("shmget failed\n");  
  15.                 return -1;  
  16.         }  
  17.         printf("create shared memory succeed: %d\n",shm_id);  
  18.         system("ipcs -m"); //查看共享内存ID  
  19.         return 0;  
  20. }  

2,附加共享内存到进程空间(shmat/shmdt)

C代码  收藏代码
  1. //attach_shm.c  
  2. #include<sys/types.h>  
  3. #include<sys/ipc.h>  
  4. #include<sys/shm.h>  
  5. #include<stdio.h>  
  6.   
  7. #define BUFSZ 1024  
  8.   
  9. int main()  
  10. {  
  11.         int *shm;  
  12.         shm = shmat(104529925,NULL,0);  
  13.         if(*shm == -1){  
  14.                 printf("shmat failed\n");  
  15.                 return -1;  
  16.         }  
  17.         printf("attach shared memory succeed: %d\n",*shm);  
  18.         system("ipcs -m"); //查看共享内存调用状态   
  19.         if(shmdt(shm) == -1){  
  20.                 printf("shmdt failed\n");  
  21.                 return -1;  
  22.         }  
  23.         system("ipcs -m"); //查看共享内存调用状态   
  24.         return 0;  
  25. }  

3,共享内存控制函数(shmctl)

 

下面写个简单的例子

共享内存写端(write_shm.c)

C代码  收藏代码
  1. //write_shm.c  
  2. #include<sys/types.h>  
  3. #include<sys/ipc.h>  
  4. #include<sys/shm.h>  
  5. #include<stdio.h>  
  6.   
  7. typedef struct  
  8. {  
  9.         char name[4];  
  10.         int age;  
  11. }people;  
  12.   
  13. int main()  
  14. {  
  15.         int i;  
  16.         char *t = 'a';  
  17.         people *p_shm = NULL;  
  18.         p_shm = shmat(104529925,NULL,0);  
  19.         if(p_shm == NULL){  
  20.                 printf("shmat failed\n");  
  21.                 return -1;  
  22.         }  
  23.         for(i=0;i<5;i++) {  
  24.                 t += 1;  
  25.                 memcpy((*(p_shm+i)).name,&t,1);  
  26.                 (*(p_shm+i)).age = 20+i;  
  27.         }  
  28.         if(shmdt(p_shm) == -1){  
  29.                 printf("shmdt failed\n");  
  30.                 return -1;  
  31.         }  
  32.         return 0;  
  33. }  

共享内存读端(read_shm.c)

C代码  收藏代码
  1. //read_shm.c  
  2. #include<sys/types.h>  
  3. #include<sys/ipc.h>  
  4. #include<sys/shm.h>  
  5. #include<stdio.h>  
  6.   
  7. typedef struct  
  8. {  
  9.         char name[4];  
  10.         int age;  
  11. }people;  
  12.   
  13. int main()  
  14. {  
  15.         int i;  
  16.         char *t = 'a';  
  17.         people *p_shm = NULL;  
  18.         p_shm = shmat(104529925,NULL,0);  
  19.         if(p_shm == NULL){  
  20.                 printf("shmat failed\n");  
  21.                 return -1;  
  22.         }  
  23.         for(i=0;i<5;i++) {  
  24.                 printf("name:%s age:%d\n",(*(p_shm+i)).name,(*(p_shm+i)).age);  
  25.         }  
  26.         if(shmdt(p_shm) == -1){  
  27.                 printf("shmdt failed\n");  
  28.                 return -1;  
  29.         }  
  30.         return 0;  
  31. }  

先后编译执行"写代码"与"读代码",结果如下

Txt代码  收藏代码
  1. root$ ./write_shm.out   
  2. root$ ./read_shm.out   
  3. name:b age:20  
  4. name:c age:21  
  5. name:d age:22  
  6. name:e age:23  
  7. name:f age:24  

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多