共享区具体操作原理:
1.先在物理内存中开辟一段空间
2.各个进程通过页表把这段物理内存映射到自己的虚拟内存地址
3.不同进程对共享内存区域进行读之后,这段内存的数据并不会被清除
共享内存是最快的进程间通信方式,通过内存映射到进程的地址空间,这些进程间通信不会再涉及到内核,也就是不再通过内核缓冲区交换数据。
用到的函数:
#include <sys/ipcs.h>
#include <sys/shm.h>
int shmget(key_t key,size_t size,int shmflg); //创建或打开共享内存
//第一个参数:key这个没啥好说的了,前面已经用过了
//第二个参数:创建的共享内存的大小
//第三个参数:跟前面的几个IPC通信方式一样,这个参数就是问以什么方式打开or创建
//返回值:共享内存id,也有说是共享内存句柄
void* shmat(int shmid,const void* shmaddr,int shmflg);
//把共享内存映射到虚拟内存上
//第一个参数:创建或打开的共享内存id,或说句柄
//第二个参数:映射到的虚拟内存地址,填0的话就由它自动分配
//第三个参数:以什么方式映射,如只读只写之类的,通常填0,默认可读可写
//返回值:映射到的虚拟内存地址
int shmdt(const void* shmaddr);
//把共享内存的虚拟内存分离,通俗讲就是取消映射了
//参数:共享内存的id
int shmctl(int shmid, int cmd, struct shmid_ds *buf);
//操作共享内存,删除,查看状态,设置等
//第一个参数:共享内存id
//第二个参数:指令,要进行什么操作,具体有什么指令直接用man查,不过IPC用来用去就那么几个,都一样的
//第三个参数:暂时先不管,我这里还没用到,后面用到再展开说说吧,这里默认先填NULL
直接上实例:
分两个程序,程序A创建共享内存并映射,然后向共享内存里写数据,程序B打开共享内存并映射,然后向共享内存读数据。
.
程序A的代码:
int main()
{
key_t shm_key;
shm_key = ftok(".",8);
int shmid;
shmid = shmget(shm_key,1024*4,IPC_CREAT|0666); //创建共享内存
if(shmid==-1){printf("creat share memory failed\n");exit(-1);} //如果创建共享内存失败,则结束程序
char *p = shmat(shmid,0,0); //创建指针指向映射的内存,这样才可以对映射到的内存进行读写
strcpy(p,"njl shi zhen de shuai a"); //把数据写入到共享内存
sleep(5); //等待5秒钟,给时间B程序读取
shmctl(shmid,IPC_RMID,NULL); //B程序读取完后,移除共享内存
}
.
程序B的代码:
int main()
{
key_t shm_key;
shm_key = ftok(".",8);
int shmid;
shmid = shmget(shm_key,1024*4,IPC_CREAT|0666);
if(shmid==-1){printf("creat share memory failed\n");exit(-1);}
char *p = shmat(shmid,0,0); //创建指针指向映射的内存,这里就相当于读取共享内存的数据了
printf("data from share memory:%s\n",p); //打印读取到的数据
}
.
.
共享内存这部分比较简单,函数也暂时没有什么复杂的操作部分,所以暂时也没有什么好说的,只是记录一下写这个demo时候的思路,方便日后用到可以快速回顾。