共享内存指 在多处理器的计算机系统中,可以被不同CPU访问的大容量内存。由于多个CPU需要快速访问存储器,这样就要对存储器进行缓存(Cache)。任何一个缓存的数据被更新后,由于其他处理器也可能要存取,共享内存就需要立即更新,否则不同的处理器可能用到不同的数据。共享内存是 Unix,linux下的多进程之间的通信方法之一 ,这种方法通常用于一个程序的多进程间通信,实际上多个程序间也可以通过共享内存来传递信息。
共享内存的不同进程可指向同一块内存地址,共享数据,减少访问cpu的时间,因此是进程间通信速度最快的。但是共享内存没有互斥,同步机制,对数据的访问可能不完整,数据读写存在相互烦扰的问题,可见共享内存这种通信方式也是有利有弊的。
函数接口
共享内存的实现主要有四个函数完成:获取共性内存shmget() ,建立连接shmat(),断开连接 shmdt(),销毁 shmctl()
头文件<sys/shm.h>
<sys/types.h>
<sys/ipc.h>
int shmget(key_t key, size_t size, int shmflg)
参数size 以页表为基本单位,是4k的整数倍(4096);
IPC_CREAT:当shmflg&IPC_CREAT为真时,如果内核中不存在键值与key相等的共享内存,则新建一个共享内存;如果存在这样的共享内存,返回此共享内存的标识符
void *shmat(int shmid, const void *shmaddr, int shmflg)
参数shmaddr指定共享内存出现在进程内存地址的什么位置
int shmdt(const void *shmaddr)
shmaddr:连接的共享内存的地址
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
参数cmd为IPC_RMID销毁共享内存
buf共享内存管理结构体
实现代码
shm.h
#ifndef _SHM_
#define _SHM_
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<sys/shm.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<sys/ipc.h>
#define PATH "."
#define PROJECT 0666
#define SIZE 4096*1
int get_shm();
char* at_shm(int shm_id);
int delete_shm(int shm_id);
int dt_shm(char* buf);
#endif
shm.c
{
int key=ftok(PATH,PROJECT);
if(key<0)
perror("ftok error");
int shm_id=shmget(key,SIZE,flag);
if(shm_id<0)
perror("shmget error");
return shm_id;
}
int get_shm()
{
int flag=IPC_CREAT|0666;
return comm_shm(flag);
}
{
return (char*)shmat(shm_id,NULL,0);
}
{
return shmdt(buf);
}
int delete_shm(int shm_id) //销毁信号
{
return shmctl(shm_id,IPC_RMID,NULL);
}
main.c
#include"shm.h"
int main()
{
int shm_id=get_shm();
pid_t id=fork();
if(id<0)
{
printf("fork error");
return 1;
}
else if(id==0) //子进程
{
char* buf=at_shm(shm_id);
if(buf!=NULL)
{
int i=0;
while(i<4096)
{
buf[i]='a';
i++;
}
buf[4095]='\0';
}
dt_shm(buf);
}
else //父进程
{
char *buf = at_shm(shm_id); //建立连接
sleep(2);
printf("%s\n", buf);
dt_shm(buf);
waitpid(id, NULL, 0);
delete_shm(shm_id);
}
return 0;
}