Linux——进程间通信之共享内存

作者:小 琛
欢迎转载,请标明出处

共享内存原理与特性

原理:创建共享内存的时候,则在物理内存中开辟一段空间,各个进程通过自己的页表结构,将物理空间映射到自己的虚拟地址空间上的共享区,各个进程通过操作自己的虚拟内存上面的共享区来进行通信。

在这里插入图片描述

特性:

  1. 共享内存是最快的进程间通信方式
  2. 共享内存是不带有同步和互斥功能的
  3. 写入数据是按照覆盖的方式进行的
  4. 生命周期跟随操作系统内核

接口函数

int shmget(key_t key,size_t size,int shmflg)

  1. 功能:创建共享内存
  2. 参数
    key:共享内存的标识符,可自己设定
    size:共享内存的大小
    shmflg:
  • IPC_CREAT:如果打开的共享内存不存在则创建,若存在,返回该内存
  • IPC_CREAT|IPC_EXCL:如果打开的共享内存存在,则报错;如果不存在,则创建。可以在后面按位或权限
  1. 返回值
    成功返回共享内存的操作句柄。

void* shmat(int shmid,const void* shmaddr,int shmflg)

  1. 功能:将共享内存附加到进程
  2. 参数
    shmid:共享内存的操作句柄
    shmaddr:映射到共享区的哪一个地址,通常穿NULL,由操作系统分配
    shmflg:
  • 0:可读可写
  • IPC_RDONLY:只读
  1. 返回值
    返回映射到共享区的一个地址

int shmdt(const void* shmaddr)

  1. 功能:分离共享区和进程
  2. 参数
    shmaddr:映射到共享区当中内存的首地址

int shmctl(int shmid,int cmd,struct shmid_ds* buf)

  1. 功能:共享内存的控制
  2. 参数
  • shmid:共享内存的操作句柄 cmd:想让该函数做什么操作
  • cmd:想让该函数做什么操作。
    IPC_STAT:获取共享内存状态。 IPC_RMID:删除共享内存
  • buf:保存共享内存信息的一个结构体,配合IPC_STAT作为出参

通信例子

shmwrite.c

 1 #include "stdio.h"                                                                                                           
  2 #include "unistd.h"
  3 #include "sys/shm.h"
  4 #define shmkey 0x99999999
  5 
  6 int main()
  7 {
  8     int shmid=shmget(shmkey,1024,IPC_CREAT|0664);
  9     if (shmid < 0)
 10     {
 11         perror("shmget");
 12         return 0;
 13     }
 14     void* adder=shmat(shmid,NULL,0);
 15     if (!adder)
 16     {
 17         perror("shmat");
 18         return 0;
 19     }
 20     int i=0;
 21     while (1)
 22     {
 23         fflush(NULL);
 24         sprintf((char*)adder,"%s -%d","xiao chen",i);
 25         printf("%s - %d\n","xiao chen",i);
 26         i++;
 27         sleep(2);
 28     }
 29     shmdt(adder);
 30     shmctl(shmid,IPC_RMID,NULL);
 31     return 0;
 32 } 

shmread.c

  1 #include "stdio.h"                                                                                                           
  2 #include "unistd.h"
  3 #include "sys/shm.h"
  4 
  5 #define shmkey 0x99999999
  6 
  7 int main()
  8 {
  9     int shmid=shmget(shmkey,1024,IPC_CREAT|0664);
 10     printf("1\n");                               
 11     if (shmid < 0)
 12     {             
 13         perror("shmget");
 14         return 0;        
 15     }            
 16     struct shmid_ds buff;
 17     shmctl(shmid,IPC_STAT,&buff);
 18     printf("shm size =%ld\n",buff.shm_segsz);
 19                                              
 20     void* adder=shmat(shmid,NULL,0);
 21     if (!adder)                     
 22     {          
 23         perror("shmat");
 24         return 0;       
 25     }            
 26     while (1)
 27     {        
 28         fflush(NULL);
 29         printf("i read [%s]\n",(char*)adder);
 30         sleep(2);
 31     }
 32     shmdt(adder);
 33     shmctl(shmid,IPC_RMID,NULL);
 34     return 0;
 35 }                  

结果
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值