共享内存
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);
}