原理
进程间通信的本质是让不同进程看到同一份资源
共享内存是内存的一部分,进程间通过共享内存通信首先申请共享内存,然后再把共享内存挂接到自己的进程地址空间(虚拟地址)的共享区,返回首地址
特性
1.共享内存没有同步互斥之类的保护机制
2.共享内存是所有进程间通信中最快的,因为拷贝少
3.共享内存内部的数据有用户维护
接口
申请共享内存
挂接地址空间
取消挂接
删除和获取共享内存属性
测试代码--利用共享内存
看看怎么利用接口,申请共享内存,挂接,删除
commom.hpp
#pragma once
#include<iostream>
#include<string>
#include<unistd.h>
#include<cstring>
#include <sys/ipc.h>
#include <sys/shm.h>
#include"log.hpp"
using namespace std;
Log log;
const int size=4096;
const string pathname="/home/defa/";
const int proj_id=0x6666;
key_t Getkey()
{
key_t key=ftok(pathname.c_str(),proj_id);
if(key<0)
{
log(Fatal,"ftok error:%s",strerror(errno));
exit(1);
}
log(Info,"get key success,key:%x",key);
return key;
}
int Getsharedmemory(int flag)
{
key_t key=Getkey();
int shmid=shmget(key,size,flag);
if(shmid<0)
{
log(Fatal,"creat share memory error:%s",strerror(errno));
exit(2);
}
log(Info,"creat share memory success,shmid:%d",shmid);
return shmid;
}
int Creatshm()
{
return Getsharedmemory(IPC_CREAT|IPC_EXCL|0664);
}
int Getshm()
{
return Getsharedmemory(IPC_CREAT);
}
client.cc
#include "commom.hpp"
int main()
{
// 客户端进行创建共享内存
int shmid = Creatshm();
// 挂接到自己的进程地址空间中
char *sharespace = (char *)shmat(shmid, nullptr, 0);
// 直接利用共享内存,进行读取,就把他当成自己的内存使用了
struct shmid_ds shmds;
while (true)
{
cout << "client say@ " << sharespace<<endl ;
sleep(1);
shmctl(shmid, IPC_STAT, &shmds);//获取共享内存属性
cout << "shm size: " << shmds.shm_segsz << endl;
cout << "shm nattch: " << shmds.shm_nattch << endl;
printf("shm key: 0x%x\n", shmds.shm_perm.__key);
cout << "shm mode: " << shmds.shm_perm.mode << endl;
}
// 取消挂接
shmdt(sharespace);
// 删除共享内存
shmctl(shmid, IPC_RMID, nullptr);
return 0;
}
server.cc
#include"commom.hpp"
int main()
{
//服务端获取共享内存
int shmid=Getshm();
//挂接
char* sharespace=(char*)shmat(shmid,nullptr,0);
//进行写入
// 一旦有了共享内存,挂接到自己的地址空间中,你直接把他当成你的内存空间来用即可!
// 不需要调用系统调用
while(true)
{
cout<<"server say@ ";
fgets(sharespace,4096,stdin);
}
//取消挂接
shmdt(sharespace);
return 0;
}