进程间通信---共享内存

共享内存:

目的: 用于进程间的数据共享
原理: 开辟一块物理内存空间,各个进程将同一块物理内存空间映射到自己的虚拟地址空间中,通过虚拟地址进行访问,进而实现数据共享

共享内存是最快的进程间通信方式,因为通过虚拟地址空间映射后,直接通过虚拟地址访问物理内存,相较于其他方式少了两部数据拷贝操作。

操作流程:
1.创建或打开共享内存
int shmget(key_t key, size_t size, int shmflg);
key:标识符—通过相同的标识符,多个进程可以打开同一块共享内存;
size:要创建的共享内存大小
shmflg:打开方式+权限;IPC_CREAT|IPC_EXCL|0664
返回值:成功返回非负整数-操作句柄;失败返回-1
2.与进程建立映射关系
void *shmat(int shmid, const void *shmaddr, int shmflg);
shmid:shmget返回的操作句柄
shmaddr:映射首地址,通常置NULL
shmflg:SHM_RDONLY-----只读; 0—可读可写
返回值:成功返回映射值后的首地址;失败返回(*void)-1
3.对共享内存进行内存操作:
memcpy,strcpy,printf…
4.与进程间解除映射关系
int shmdt(void *shmaddr)
shmaddr:shmat返回的映射首地址
返回值:成功返回0,失败返回-1;
5.删除共享内存
int shmctl(int shmid,int cmd,struct shmid_ds *buf)
shmid:shmget返回的操作句柄
cmd:要对共享内存进行的操作类型
IPC_RMID:标记要删除的共享内存
映射连接数为0时删除共享内存;禁止新的映射连接
buf:用于获取或设置共享内存属性的,简单使用置NULL即可
返回值:成功返回0;失败返回-1
代码:

 //shm_read.c
 #include<stdio.h>  //printf
 #include<unistd.h>
 #include<sys/shm.h>
 #include<stdlib.h>
 
 #define  IPC_KEY  0x01234567
 
 int main(int argc,char *argv[]) //运行参数个数  运行参数字符串首地址
 {
   //1.创建或打开共享内存
   //int shmget(标识,共享内存大小,权限+打开方式)
   int shmid=shmget(IPC_KEY,32,IPC_CREAT|0664);
   if(shmid<0){
      perror("shmget error");
      return -1;
   }
   //2.与进程间建立映射关系
   //void *shmat(操作句柄,映射首地址,访问方式)
   void *shm_start=shmat(shmid,NULL,0);  //0---可读可写   SHM_RDONLY----只读
   if(shm_start==(void*)-1){
       perror("shmat error");
       return -1;
   }
   //3.对共享内存进行内存操作
   while(1){
     printf("%s\n",(char*)shm_start);
     sleep(1);                                                                                                                                                        
   }
   //4.与进程间解除映射关系
   //int shmdt(void *shmaddr)
   shmdt(shm_start);
   //5.删除共享内存
   //int shmctl(操作句柄,操作类型,信息结构)
   shmctl(shmid,IPC_RMID,NULL);
   return 0;

}

//shm_write.c
 #include<stdio.h>
 #include<unistd.h>
 #include<sys/shm.h>
 #include<stdlib.h>
 
 #define IPC_KEY 0x01234567
 
 int main(int argc,char *argv[]) //运行参数个数  运行参数首地址
 {
   //1.建立或开辟共享内存
   //int shmget(内存标记,内存大小,打开方式+权限)
   int shmid=shmget(IPC_KEY,32,IPC_CREAT|0664);
   if(shmid<0){
     perror("shmget error");
     return -1;
   }
   //2.与进程建立映射关系
   //void* shmat(标志,映射首地址,访问方式)
   void *shm_start=shmat(shmid,NULL,0);
   if(shm_start==(void*)-1){
     perror("shmat error");
     return -1;
   }
   //3.对共享内存进行内存操作
   int i=0;
   while(1){
     scanf(shm_start,"今天你开心吗?+%d",i++);
     sleep(1);
   }
   //4.解除映射关系
   //int shmdt(void *shmaddr)
   shmdt(shm_start);
   //5.删除共享内存
   shmctl(shmid,IPC_RMID,NULL);
 
   return 0;    
 }

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值