进程间通信之共享内存讲解

共享内存

进程间通信的另外一种方式-----共享内存



引入

多个进程申请同一块内存区域用于通信
shell命令:
查看共享内存------- ipcs -m
删除共享内存-------ipcrm -m 共享内存的id


提示:以下是本篇文章正文内容,下面案例可供参考

一、申请共享内存

#include <sys/shm.h>
int shmget(key_t key,size_t size,int shmflg);
返回值: 成功 返回共享内存的id号
失败 -1
参数 :key(重点,重点) 键值
有两种写法:
写法一:程序员随便写一个无符号正整数即可
写法二:调用系统提供的专门生成key值的函数ftok()
#include <sys/ipc.h>
key_t ftok(const char *pathname, int proj_id);
返回值: 根据你传递的路径和整数计算一个独一无二的键值
参数:pathname --》任意一个linux系统中的合法路径
proj_id --》任意一个整数
size --》你要申请的共享内存的大小, 字节 512字节的整数倍
shmflg --》IPC_CREAT IPC_EXCL 0777
类似于O_CREAT O_EXCL

二、映射得到共享内存的首地址

void *shmat(int shmid, const void *shmaddr, int shmflg); //类似于mmap()
返回值:成功 映射得到的共享内存的首地址
失败 NULL
参数:shmid --》共享内存的id,shmget的返回值
shmaddr --》默认设置为NULL,表示由操作系统自动给我分配共享内存
shmflg --》设置为0,表示共享内存是可读可写的

三、解除映射

int shmdt(const void *shmaddr);
参数:shmaddr --》你刚才映射得到的首地址

四、多功能函数,删除共享内存(获取,设置共享内存的属性)

int shmctl(int shmid, int cmd, struct shmid_ds *buf);
参数:cmd --》IPC_STAT 获取共享内存的属性信息
IPC_SET 设置共享内存的属性信息
IPC_RMID 删除共享内存
struct shmid_ds --》用来存放获取,设置的共享内存属性
{
shm_perm; //存放权限
shm_segsz; //存放大小
}

五、相关的主要代码

1.创建共享内存

/*
	设置当前共享内存的属性 
	共享内存的大小不能改 
*/

int main()
{
	int shmid;
	struct shmid_ds myds;  
	//清空 
	bzero(&myds,sizeof(myds)); 
	myds.shm_segsz = 2048;  //大小不能修改 
	myds.shm_perm.mode = 0666;  //权限可以 
	//生成键值
	key_t key = ftok("/home/gec",5);
	//申请共享内存
	shmid = shmget(key,1024,IPC_CREAT|IPC_EXCL|0777);
	if(shmid == -1){
		if(errno == EEXIST){   //共享内存存在 
			shmid = shmget(key,1024,0777);
		}
		else{
			perror("shmget");
			return -1;	
		}
	} 
	printf("shmod is : %d\n",shmid); 
	
	//设置刚才申请的那个共享内存的属性信息
	shmctl(shmid,IPC_SET,&myds); 
	
	
}

2.得到共享内存

/*
	获取共享内存的属性信息 

*/

int main()
{
	int shmid;
	struct shmid_ds myds;  //这个变量相当于容器 
	//生成键值
	key_t key = ftok("/home/gec",5);
	//申请共享内存
	shmid = shmget(key,1024,IPC_CREAT|IPC_EXCL|0777);
	if(shmid == -1){
		if(errno == EEXIST){   //共享内存存在 
			shmid = shmget(key,1024,0777);
		}
		else{
			perror("shmget");
			return -1;	
		}
	} 
	printf("shmod is : %d\n",shmid); 
	
	//获取刚才申请的那个共享内存的属性信息
	shmctl(shmid,IPC_STAT,&myds); 
	printf("The size of the current shared file : %d\n",myds.shm_segsz);
	printf("Permissions for current shared file : %o\n",myds.shm_perm.mode); 
	
}

3.删除共享内存


/*
	删除当前的共享内存 
	要切换到超级用户
	sudo -m   //命令行 
	
*/

int main()
{
	int shmid;
	struct shmid_ds myds;  
	//清空 
	bzero(&myds,sizeof(myds)); 
	myds.shm_segsz = 2048;  //大小不能修改 
	myds.shm_perm.mode = 0666;  //权限可以 
	//生成键值
	key_t key = ftok("/home/gec",5);
	//申请共享内存
	shmid = shmget(key,1024,IPC_CREAT|IPC_EXCL|0777);
	if(shmid == -1){
		if(errno == EEXIST){   //共享内存存在 
			shmid = shmget(key,1024,0777);
		}
		else{
			perror("shmget");
			return -1;	
		}
	} 
	printf("shmod is : %d\n",shmid); 
	
	//删除刚才申请的那个共享内存的属性信息
	shmctl(shmid,IPC_RMID,NULL); 
	
	
}

4.ftok()

int main()
{
	//ftok生成键值
	key_t key1 = ftok("/home/gec",4554);
	printf("key1 = %ld\n",key1);
	
	key_t key2 = ftok("/home/gec",4555);
	printf("key2 = %ld\n",key2);
	
	key_t key3 = ftok("/home/gec",4554);
	printf("key3 = %ld\n",key3);
}


六、相关图示

帮助大家理解:(重点部分)

在这里插入图片描述

总结

提示:这里对文章进行总结:
以上就是今天要讲的内容,本文仅仅简单介绍了进程间通信方式中的一种,共享内存,本博客的其他文章中有对别的方式的讲解,有需要的朋友可以看看,希望可以帮助到大家。【可爱】【可爱】

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值