共享内存的使用步骤 server端和client端
server端:
1.获取key值 --> ftok
2.创建共享内存 --> shmget flags==IPC_CREAT | IPC_EXCL
3.进程和共享内存进行挂接(关联) --> shmat
void *shmat(int shmid, const void *shmaddr, int shmflg); --> shmflg设为0表示默认为可读可写
4.使用共享内存进行通信
5.进程和共享内存进行取消关联 --> shmdt
6.删除共享内存 --> shmctl
client端:
1.获取key值
2.获取server端创建的共享内存 --> shmget flags==IPC_CREAT
3.进程和共享内存进行挂接(关联) --> shmat
4.使用共享内存进行通信
5.进程和共享内存取消关联 --> shmdt
查看IPC方式的通信资源
1.ipcs -m --> 查看共享内存
2.ipcs -q --> 查看消息队列
3.ipcs -s --> 查看信号量
ipcrm -m 指定shmid 删除一个共享内存
所有System V系列的IPC通信方式比如共享内存,信号量,消息队列,他们的生命周期不随进程的结束而结束,是随操作系统的。如果需要删除,必须手动删除
System V系列的通信方式都是作用于同一台主机上的不同进程
POSIX 系列的通信方式可以作用于不同主机上的不同进程
共享内促你的大小一般建议设置为4KB的整数倍-->因为操作系统分配共享内存的大小时是以4KB为基本单位的
//comm.hpp
#ifndef __COMM_HPP
#include <iostream>
#include <cstdio>
#include <cerrno>
#include <cstring>
#include <unistd.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#define __COMM_HPP
#endif
#define PATHNAME "/tmp"
#define PROJID 1
#define MAX_SIZE 4096
key_t getKey()
{
key_t key = ftok(PATHNAME, PROJID);
if (key == -1)
{
std::cout << "getKey()" << errno << ":" << strerror(errno);
exit(1);
}
return key;
}
int createShm(key_t key)
{
int shmid = shmget(key, MAX_SIZE, IPC_CREAT | IPC_EXCL | 0600);
if (shmid == -1)
{
std::cout << "createShm" << errno << ":" << strerror(errno);
exit(2);
}
return shmid;
}
int getShm(key_t key)
{
int shmid = shmget(key, MAX_SIZE, IPC_CREAT);
if (shmid == -1)
{
std::cout << "getShm" << errno << ":" << strerror(errno);
exit(2);
}
return shmid;
}
void *connectShm(int shmid)
{
void *start = shmat(shmid, nullptr, 0);
if ((long long)start == -1L)
{
std::cout << "connectShm" << errno << ":" << strerror(errno);
exit(3);
}
return start;
}
void disconnectShm(const void *start)
{
int ret = shmdt(start);
if (ret == -1)
{
std::cout << "disconnectShm" << errno << ":" << strerror(errno);
exit(4);
}
}
void destroyShm(int shmid)
{
int ret = shmctl(shmid, IPC_RMID, nullptr);
if (ret == -1)
{
std::cout << "destroyShm" << errno << ":" << strerror(errno);
}
}
//shm.client.cc
#include "comm.hpp"
int main(){
//获取key值
key_t key = getKey();
//获取共享内存
int shmid = getShm(key);
printf("key:%x,shmid:%d\n",key,shmid);
//和共享内存建立挂接
char* start = (char*)connectShm(shmid);
//使用共享内存进行通信
int cnt = 0;
while(1){
const char* buf = "hello server,我是客户端,我在给你发消息";
snprintf(start,MAX_SIZE,"[第%d次消息]:%s",++cnt,buf);
sleep(1);
}
//和共享内存取消挂接
disconnectShm(start);
//进程退出
return 0;
}
//shm.server.cc
#include "comm.hpp"
int main(){
//获取key值
key_t key = getKey();
//创建共享内存
int shmid = createShm(key);
printf("key:%x,shmid:%d\n",key,shmid);
//和共享内存挂接
char* start = (char*)connectShm(shmid);
//使用共享内存进行通信
while(1){
std::cout << "#client->server" << start << std::endl;
sleep(1);
}
//和共享内存取消挂接
disconnectShm(start);
//删除共享内存
destroyShm(shmid);
return 0;
}
//makefile
.PHONY:all
all:shm_server shm_client
shm_server:shm_server.cc
g++ -o $@ $^ -std=c++11
shm_client:shm_client.cc
g++ -o $@ $^ -std=c++11
.PHONY:clean
clean:
rm -f shm_server shm_client