版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_37964044/article/details/81591634
共享内存:就是指把一段物理内存(共享内存)映射到不同进程的虚拟地址空间,两个进程只要操纵自己的虚拟地址空间便可访问物理内存,从而实现进程间的通信。
如下图:
要用共享内存进行通信,我们要做到?
1.如何让共享内存映射到你进程的虚拟地址空间
2.如何创建一个共享内存
我们接着往下看
创建或打开共享内存
创建或打开共享内存
函数原型:
int shmget(key_t key,size_t size,int shmflg)
参数:key共享内存的名字
size表示共享内存的大小
shmflg 创建:IPC_CREAT|0644
打开:0
返回值:失败返回-1,成功返回该共享内存段的标识码
将共享内存和进程虚拟地址空间挂接
将共享内存连接到虚拟地址空间
函数原型:void* shmat(int shmid,void *shmaddr,int shmflag)
参数:shmid:共享内存标识
shmaddr:指定连接的地址,一般设置为NULL(一般我们都不知道,要连接那里,你知道哪里没数据码,我不知道。因此设置为NULL,表示让操作系统帮我们选一个)
shmflg:不关心设置为0
返回值:成功返回:操作系统给你指定的那个虚拟空间上的地址
失败返回:-1
将共享内存和进程地址空间脱离
将共享内存和进程虚拟地址空间脱离
函数原型:
int shmdt(const void* shmaddr)
参数:shmaddr:是shmat返回的指针
返回值:成功返回0,失败返回-1
注意:将共享内存和当前进程脱离,并不是说删除了共享内存
用于控制共享内存
用于控制共享内存
函数原型:
int shmctl(int shmid,int cmd,struct shmid_ds* buf)
参数:shmid:共享内存标识码
cmd:IPC_RMID,表示删除共享内存
第三个参数不关心置为0
返回值:成功0 失败-1
共享内存这块常用的命令
ipcs -m用于查看共享内存
ipcrm -m semid用于删除共享内存
ipcrm -M key用于删除共享内存
共享内存的优点:
是最快的进程间通信方式
原因:一旦和你进程地址空间建立关系,你在自己进程地址空间内操作,就和操作共享内存一样,不用切换到内核,(而消息队列都是先要从用户态切换到内核态,再从内核态切换到用户态。)因此特别快。
共享内存的特点:
1.能够应用于任何进程之间
2.双向通信,每个进程可读,可写
3,没有面向字节流,面向数据块的概念,随机访问内存中数据
4.没有内置同步互斥机制
5.生命周期随内核
简单代码实现:
shmget.c
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
struct stu
{
int id;
char name[20];
};
int main()
{
int shmid=shmget(1234,sizeof(struct stu),IPC_CREAT|0644);
if(shmid==-1)
{
perror("-1");
exit(1);
}
printf("creat ok\n");
return 0;
}
read.c
#include<stdlib.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
struct stu
{
int id;
char name[20];
};
int main()
{
int shmid=shmget(1234,0,0);
if(shmid==-1)
{
perror("-1");
exit(1);
}
struct stu * p=(struct stu*) shmat(shmid,NULL,0);
printf("p->id=%d,p->name=%s\n",p->id,p->name);
shmdt(p);
return 0;
}
~
write.c
#include<stdlib.h>
#include<string.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
struct stu
{
int id;
char name[20];
};
int main()
{
int shmid=shmget(1234,0,0);
if(shmid==-1)
{
perror("-1");
exit(1);
}
struct stu * p=(struct stu*) shmat(shmid,NULL,0);
p->id=1;
strcpy(p->name,"fu rong jie jie");
sleep(30);
shmdt(p);
return 0;
}
del.c
#include<sys/ipc.h>
#include<sys/shm.h>
int main()
{
int id=shmget(1234,0,0);
shmctl(id,IPC_RMID,0);
}