共享内存,就是允许两个不相关的进程访问同一个逻辑内存,然后进行通信
1.数据的共享进程间的数据直接访问内存,是最快的进程通信方式,但并未提供同步机制,通常需要用其他的机制来同步,例如信号量
2.共享内存代码申请的适合,尽量是一页大小4k的倍数申请,否则容易产生内存碎片
这里用一张图来说明:
两个不同的虚拟地址通过页表映射到物理空间的同一区域,它们所指向的这块区域即共享内存。
代码实现:
int shmget(key_t key, size_t size, int shmflg);//创建共享内存
void *shmat(int shmid, const void *shmaddr, int shmflg);//挂载共享内存
int shmdt(const void *shmaddr);//删除与共享内存的关联
int shmctl(int shmid, int cmd, struct shmid_ds *buf);//销毁共享内存
1.func.h
#pragma once
#include <stdio.h>
#include <error.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<unistd.h>
constexpr auto PATHNAME = ".";
constexpr auto PROJ_ID = 066;
int CreatShmid(int size);
int GetShmid(int size);
int Destory(int shmid);
int commShmid(int size, int flag)//创建
{
key_t key = ftok(PATHNAME, PROJ_ID);
if (key > 0)
{
return shmget(key, size, flag);
}
else
{
perror("ftok");
return -1;
}
}
int CreatShmid(int size)//创建
{
return commShmid(size, IPC_CREAT | IPC_EXCL | 0666);
}
int GetShmid(int size)//获取shmid
{
return commShmid(size, IPC_CREAT);
}
int Destory(int shmid)//销毁
{
return shmctl(shmid, 0, IPC_RMID);
}
2.进程A.cpp
#include "func.h"
int main()
{
int shmid=CreatShmid(4097);
if(shmid>0)
{
int i=0;
char *addr=shmat(shmid,NULL,0);
while(i<20)
{
addr[i++]='A';
addr[i]='\0';
sleep(1);
}
if(shmdt(addr)==-1)
{
perror("shmat");
return -3;
}
}
else
{
perror("CreatShmid");
return -1;
}
if(Destory(shmid)<0)
{
perror("Destory");
return -2;
}
return 0;
}
3.进程B.cpp
#include "comm.h"
int main()
{
int shmid=GetShmid(4097);
if(shmid>0)
{
int i=0;
char *addr=shmat(shmid,NULL,0);
while(i<20)
{
printf("%s\n",addr);
sleep(1);
i++;
}
if(shmdt(addr)==-1)
{
perror("shmdt");
return-1;
}
}
else
{
perror("GetShmid");
return -2;
}
return 0;
}
运行结果