ipc共享内存

共享内存

1.概念

每个ipc对象都有唯一的ID用key关联

ipc对象创建后一直存在,直到显示的删除

可以用ipcs查看ipc创建的ipc对象

•共享内存是一种最为高效的进程间通信方式,进程可以直接读写内存,而不需要任何数据的拷贝

•共享内存在内核空间创建,可被进程映射到用户空间访问,使用灵活

•由于多个进程可同时访问共享内存,因此需要同步和互斥机制配合使用

2.相关api

ftok函数创建key

#include <sys/types.h>
#include <sys/ipc.h>

key_t ftok(const char *path,int proj_id)
	path:存在且可访问的文件的路径
	proj_id:用于生成key的数字,范围1-255
	成功时返回合法的key值,失败时返回EOF

创建/打开共享内存

#include <sys/ipc.h>
#include <sys/shm.h>

int shmget(key_t key,int size,int shmflg)
	key:和共享内存关联的key,IPC_PRIVATE或ftok生成
	shmflg:共享内存标志位 IPC_CREAT|0666
	成功时返回共享内存的id,失败时返回EOF

映射共享内存,即把指定的共享内存映射

#include <sys/ipc.h>
#include <sys/shm.h>

void *shmat(int shmid,const void *shmaddr, int shmflg)
	shmid:要映射的共享内存id
	shmaddr:映射后的地址,NULL表示由系统自动映射
	shmflg:标志位 0表示可读写;SHM_RDONLY表示只读
	成功时返回映射的地址,失败时返回(void *)-1

读写共享内存

strcpy()
读地址中的内容

撤销共享内存

#include <sys/ipc.h>
#include <sys/shm.h>

int shmdt(void *shmaddr)
	不使用共享内存时应撤销映射,进程结束时自动撤销
	成功返回0,失败时返回EOF

共享内存控制

共享内存删除的时间点
	添加删除标记
	nattach变成0时真正删除
#include <sys/ipc.h>
#include <sys/shm.h>

int shmctl(int shmid,int cmd,struct shmid_ds *buf)
	shmid:要操作的共享内存的id
	cmd:要执行的操作 IPC_STAT IPC_SET IPC_RMID
	buf:保存或设置共享内存属性的地址
3.测试
3.1 写
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

/*测试结构体*/
typedef struct testdata		
{
	int a;
	int b;
}Data,*DATA;


int main()
{
	/* 1.合成key值 */
	key_t key = ftok("tmp",1);
	if(key < 0)
	{
		perror("ipc key error\n");
		return -1;
	}
	/* 2.创建共享内存 */
	int shmid = shmget(key,512,IPC_CREAT|IPC_EXCL|0666);
	if(shmid < 0)
	{
		perror("shmid is error\n");
		return -1;
	}
	DATA shmaddr = NULL;
	/* 3.映射共享内存 */
	shmaddr = shmat(shmid,NULL,0);
	if(shmaddr == (void *) -1)
	{
		perror("shmat error\n");
		return -1;
	}
	/* 4.写入数据 */
	shmaddr->a = 1;
	shmaddr->b = 2;
	/* 5.取消内存映射 */
	shmdt(shmaddr);
	return 0;
}
3.2 读
#include <stdio.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

typedef struct testdata
{
	int a;
	int b;
}Data,*DATA;


int main()
{    
	/* 1.合成key值 */
	key_t key = ftok("tmp",1);
	if(key < 0)
	{
		perror("ipc key error\n");
		return -1;
	}
	/* 2.创建共享内存 */
	int shmid = shmget(key,512,0666);
	if(shmid < 0)
	{
		perror("shmid is error\n");
		return -1;
	}
	DATA shmaddr = NULL;
	/* 3.映射共享内存 */
	shmaddr = shmat(shmid,NULL,0);
	if(shmaddr == (void *) -1)
	{
		perror("shmat error\n");
		return -1;
	}
	/* 4.写入数据 */
	printf("a = %d b = %d \n",shmaddr->a,shmaddr->b);
	/* 5.取消映射 */
	shmdt(shmaddr);
	/* 6.删除共享内存 */
	shmctl(shmid,IPC_RMID,NULL);
	return 0;
}
4.测试结果

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值