共享内存
进程间通信的本质是让不同的进程访问一块公共的资源。
1、共享内存是进程间通信最快的方式(为什么)
2、共享内存不提供任何的同步与互斥关系。(由用户维护,可以用信号量)
以下图解释了问题1,原因是,由于共享内存的机制,两个进程不需要拷贝拷贝数据,这个特点可能在数据较少的情况下看不出来,但是数据较多时,优势较为明显。
下图是shmat之前之后的共享内存示意图:(shmget获得共享内存后需要挂接)
![]() |
函数:
用于Linux进程通信共享内存。共享内存函数由shmget、shmat、shmdt、shmctl四个函数组成。
shmat(把共享内存区对象映射到调用进程的地址空间)
void *shmat(int shmid, const void *shmaddr, int shmflg)
参数:
shmid | 共享内存标识符 |
shmaddr | 指定共享内存出现在进程内存地址的什么位置,直接指定为NULL让内核自己决定一个合适的地址位置 |
shmflg | 如果设置为SHM_RDONLY是只读模式,其他为读写模式 |
返回值:成功返回附加好的共享内存地址
shmdt(断开共享内存连接)
int shmdt(const void *shmaddr)
参数:
shmaddr:连接的共享内存的起始地址
返回值:成功返回0
shmget(得到一个共享内存标识符或创建一个共享内存对象)
int shmget(key_t key, size_t size, int shmflg)
参数:
key | 大于0的32位整数:视参数shmflg来确定操作。通常要求此值来源于ftok返回的IPC键值 |
size | 大于0的整数:新建的共享内存大小,以字节为单位 |
flags | 有IPC_CREAT和IPC_EXCL(用法同前面写的一致) |
返回值:成功返回共享内存标示符
注:system V分配内存的方法以页为基本单位,一般以页的整数倍分配。
shmctl完成对共享内存的控制
int shmctl(int shmid, int cmd, struct shmid_ds *buf)
参数:
shmid | 共享内存标识符 | |
cmd | IPC_STAT:得到共享内存的状态,把共享内存的shmid_ds结构复制到buf中 | |
IPC_SET:改变共享内存的状态,把buf所指的shmid_ds结构中的uid、gid、mode复制到共享内存的shmid_ds结构内 | ||
IPC_RMID:删除这片共享内存 | ||
buf | 共享内存管理结构体。具体说明参见共享内存内核结构定义部分 |
共享内存实现通信的例子
comm.h
#pragma once
#include<errno.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<string.h>
#define _PATH_NAME_ "/temp"
#define _PROJ_ID_ 0x6666
int create_shm(int size);
int get_shm();
int destory_shm(int shm_id);
void* shm_at(int shm_id);
int shm_dt(void*shmaddr);
comm.c
#include"comm.h"
static int comm_create_shm(int size,int flags)
{
key_t _key = ftok(_PATH_NAME_,_PROJ_ID_);
if(_key<0)
{
perror("ftok");
return -1;
}
// int shm_id=shmget(_key,size,IPC_CREAT | IPC_EXCL);
int shm_id=shmget(_key,size,flags);
if(shm_id < 0)
{
perror("shmget");
return -2;
}
return shm_id;
}
int create_shm(int size)
{
int flags = IPC_CREAT | IPC_EXCL|0666;
return comm_create_shm(size,flags);
}
int get_shm()
{
int flags = IPC_CREAT;
return comm_create_shm(0,flags);
}
int destory_shm(int shm_id)
{
if(shmctl(shm_id,IPC_RMID,NULL)<0)
{
perror("shmctl");
return -1;
}
return 0;
}
void* shm_at(int shm_id)
{
return shmat(shm_id,NULL,0);
}
int shm_dt(void* shmaddr)
{
return shmdt(shmaddr);
}
server.c
#include"comm.c"
int main()
{
int shm_id = create_shm(4096);
sleep(5);
char* buf = (char*)shm_at(shm_id);
sleep(1);
sleep(1);
while(1)
{
printf("%s\n",buf);
sleep(1);
if(strcmp(buf,"AAAAA") == 0)
{
break;
}
}
shm_dt(buf);
sleep(5);
destory_sem(sem_id);
return 0;
}
client.c
#include"comm.c"
int main()
{
int shm_id = get_shm();
char* buf = (char*)shm_at(shm_id);
int index = 0;
while(1)
{
buf[index++]='A';
buf[index]='\0';
sleep(1);
if(index>5)
{
break;
}
}
sleep(5);
shm_dt(buf);
sleep(5);
return 0;
}
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。