进程间的通信4 共享内存

共享内存

1.共享内存简介

  • 共享内存是将分配的物理空间直接映射到进程的用户虚拟地址空间中,减少数据在内核空间缓存
  • 共享内存是一种效率较高的进程间通讯的方式
  • 在 Linux 系统中通过 ipcs -m 查看所有的共享内存
    在这里插入图片描述
  • 共享内存模型图
    在这里插入图片描述

2.共享内存的创建

1.函数头文件
#include<sys/ipc.h>
#include<sys/shm.h>
2.函数原型
intshmget(key_tkey,size_tsize,intshmflg);
3.函数功能
创建一个共享内存,并返回ID
4/函数参数
		key:ftok()函数返回
		size:共享内存的大小
		shmflg:共享内存标志
5.函数返回值
成功:返回共享内存id
失败:返回-1,并设置errno

3.共享内存的删除

1.函数头文件
#include<sys/ipc.h>
#include<sys/shm.h>
2.函数原型
int shmctl(int shmid,int cmd,struct shmid_ds*buf);
3.函数功能
共享内存控制函数,功能由具体的功能命令字决定
4.函数参数
		shmid:共享内存id 
		cmd:控制命令字
			IPC_STAT:获取消息队列属性
			IPC_SET:设置消息队列属性
		I	PC_RMID:删除消息队列属性,用此命名时,第三个参数为NULL buf:共享内存属性结构体指针
5.函数返回值
成功:返回0,特殊命令字除外
失败:返回-1

4.共享内存映射

1.函数头文件
#include<sys/types.h>
#include<sys/shm.h>
2.函数原型
void*shmat(int shmid,const void*shmaddr,int shmflg);
3.函数功能
将进程地址空间映射到共享内存上
4.函数参数
shmid:共享内存id
shmaddr:指定映射到进程地址空间的起始地址,指定为NULL,由系统选择映射的地址shmflg:共享内存标志,一般设置为0
5.函数返回值
成功:返回映射到进程地址空间的起始地址
失败:(void*)-1,并设置errno

5.共享内存解除映射

1.函数头文件
#include<sys/types.h>
#include<sys/shm.h>
2.函数原型
intshmdt(constvoid*shmaddr);
3.函数功能
解除进程地址空间与共享内存的映射
4.函数参数
shmaddr:映射地址空间的起始地址
5.函数返回值
成功:返回0
失败:返回-1,并设置errno

6.测试案列(在文件输出内容):

share_write.c:

#include <sys/types.h>
#include <sys/ipc.h>
#include <string.h> 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/shm.h>
#define PATH "/home/linuxfu"
#define SIZE 1024
int main(){
	key_t key = ftok(PATH,70);
	if(key == -1){
		perror("key");
		exit(EXIT_FAILURE);
	}
	//设置共享内存 
	int shmid = shmget(key,SIZE,0666 | IPC_CREAT);
	if(shmid == -1){
		perror("shmid");
		exit(EXIT_FAILURE);
	} 
	//挂接共享内粗
	void * share_add = shmat(shmid,NULL,0);
	if(share_add == (void*)-1){
		perror("share_add");
		exit(EXIT_FAILURE);
	}
	char buf[SIZE] = { 0 };
	fgets(buf,sizeof(buf) - 1,stdin);
	buf[strlen(buf) - 1]  = '\0'; 
	strcpy((char*)share_add,buf); 
	//挂断
	shmdt(share_add); 
}

share_read.c:

#include <sys/types.h>
#include <sys/ipc.h>
#include <string.h> 
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <sys/shm.h>
#define PATH "/home/linuxfu"
#define FILENAME "log.txt"
#define SIZE 1024
int main(){
	key_t key = ftok(PATH,70);
	if(key == -1){
		perror("key");
		exit(EXIT_FAILURE);
	}
	//设置共享内存 
	int shmid = shmget(key,SIZE,0666 | IPC_CREAT);
	if(shmid == -1){
		perror("shmid");
		exit(EXIT_FAILURE);
	} 
	//挂接共享内粗
	void * share_add = shmat(shmid,NULL,0);
	if(share_add == (void*)-1){
		perror("share_add");
		exit(EXIT_FAILURE);
	}
	FILE * pf = fopen(FILENAME,"w+");
	if(pf == NULL){
		perror("pf");
		exit(EXIT_FAILURE);
	}	
	fputs((char*)share_add,pf);
	shmdt(share_add); 
	shmctl(shmid,IPC_RMID,NULL);
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值