IPC之共享内存

1.使用共享内存一般步骤 :
1.1获得共享内存对象的ID:shmget()
1.2将共享内存映射至本进程虚拟内存空间的某个区域:shmat()
1.3当不适用时,解除映射关系shmdt()
1.4当所有进程都不用共享内存之时,删除共享内存shmctl()

2. 共享内存的创建函数shmget
在这里插入图片描述
注意:
参数 key:IPC_PRIVATE 或 ftok的返回值,IPC_PRIVATE会生成相同的key值,ftok生成不同的key值
参数size:申请共享内存的大小 ,第一次申请的共享内存的大小决定了他的上限,并且只要你没有进行过删除这段共享内存的操作,这段共享内存会一直存在。要想申请这段共享内存成功需要确认几点:内存大小比能申请的最小值大且比最大值小,若以该键值申请过共享内存了,之后所申请的内存大小要比第一次开的内存大小要只小不大(同一key值第一申请内存大小为最大,后续要改只能比第一次申请的内存要小,不同key值不影响,不超过申请内存上限就好)。
参数mode:与open函数的mode一样,用来设置内存的权限

要查看共享内存能开的最大最小值的命令是:
cat /proc/sys/kernel/shmmax
cat /proc/sys/kernel/shmmni
然后发现最小值是4096,最大值是18446744073692774399

3.共享内存的映射和解除映射函数
在这里插入图片描述
注意:
参数shmid:shmget函数返回值的ID号
参数shmaddr:映射到的地址,NULL为系统自动完成的映射(推荐)
参数shmflg: SHM_RDONLY共享内存只读,默认是0,表示可读写

4.获取或者设置共享内存的相关属性
在这里插入图片描述
注意:
当有进程在使用共享内存块时,无法删除共享内存,等待所有进程使用shmdt脱离共享内存映射,才能删除

5.例子:
注意:如果想要两个或多个进程同时使用同一块共享内存,需要fotk(const char *pathname, proj_id)的两个参数一模一样,生成相同的key值,然后用shmget获取共享内存,再用shmat映射共享内存就可以两个进程间访问同一块内存了(在Ubuntu16试过)。

#include "sys/types.h"
#include "sys/shm.h"
#include "signal.h"
#include "unistd.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"

int main()
{
  int shmid;
  int key;
  char systemBuf[20] = {0};
  char *p = NULL;
  
  key=ftok("./",'b');	//当前进程路径生成key值
  if(key <0 )
  {
	printf("creat key fialure\n");
	return -2;
  }
  
  printf("creat key sucess key=%X\n",key);
  shmid=shmget(key,128,IPC_CREAT | 0777);	//生成共享内存,并返回共享内存ID
  if(shmid <0)
  {
	printf("creat share memory failure\n");
	return -1;
  }
  printf("creat share memory sucess shmid=%d\n",shmid); 
  system("ipcs -m");						//相当于在终端输入命令#ips -m
 

  p=(char *)shmat(shmid,NULL,0);			//在本进程内共享内存的映射,映射之后才能在进程中使用,类似于malloc()和数组
  if(p == NULL)
  {
	printf("shmat function failure\n");
	return -3;
  }
  
  fgets(p,128,stdin);							//write share memory 
  printf("share memory data:%s",p);				//start read share memory
  printf("second read share memory data:%s",p);	//跟管道不同,于数组相同,只要没有将内存清除,数据就不是丢失,读取多少遍都一样
 
  shmdt(p);		//删除对共享内存的映射,删除后该进程无法再访问共享内存,但是共享内存还是存在
 
  
  shmctl(shmid,IPC_RMID,NULL);					//删除共享内存,完完全全删除,消息在Linux中
//  sprintf(systemBuf, "ipcrm -m %d", shmid);	//删除共享内存,完完全全删除,消息在Linux中
//  system(systemBuf);
  
  system("ipcs -m");
  
  return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值