进程间的通信方式之共享内存
1 说明
以一对情侣来做比喻,例如一男女进行约会,双方用纸条进行信息的交流,假设双方之间有一张桌子,桌子上有一张纸,男的可以通过把自己的想法通过面前的纸张写下来,直接给女方看,同一个道理,用进程来说的话,有两个进程A,B,A进程有自己的独立空间,B进程也有自己的独立的空间,独立的进程空间不会相互交流,但在内存中有一块公共的内存空间,而这个公共的内存地址A和B都可以拿得到,它们俩可以面向同一个物理空间,如果A有一个指针指向该公共的地址空间,虽然该指针的地址不在A的空间中,但A可以读取到该指针地址里面的内容,同一个道理B也如此。
那实现共享内存的编程思路是什么呢?
- 首先要创建一个共享内存空间,如果有的话直接打开
- 映射,把共享空间映射到A,B空间
- 接着就可以进行数据的交换了
- 数据交换完要释放共享内存
2 共享内存的代码原型有:
1 #include <sys/shm.h>
2 int shmget(key_t key, size_t size, int shmflag);
// 创建或获取一个共享内存:成功返回共享内存ID,失败返回-1
Size:共享内存的大小,必需以兆对齐的,因此给它开辟一个兆级空间
例:shmid = shmget(key,1024*4,IPC_CREAT|0666);
3 void *shmat(int shmid, const void *shmaddr, int shmflag);
// 连接共享内存到当前进程的地址空间:成功返回指向共享内存的指针,失败返回-1
Shmid:就是我们获取上面shmid的ID shmid = shmget(key_t key, size_t size, int shmflag);
Shmaddr:我们一般取0,为我们自动的安排共享内存。
Shmflag:我们一般也取0,0代表映射进来的共享内存可读可写。当然也可以自己安排
例:shmat(shmid,0,0);
4 int shmdt(void *addr);
// 断开与共享内存的连接:成功返回0,失败返回-1
5 int shmctl(int shmid, int cmd, struct shmid_ds *buf);
// 去掉共享内存的相关信息防止占用空间:成功返回0,失败返回-1
Smd:是指令
3 例子
通过简单的例子来实践一下
shmw.c
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
int shmid;
char *shmaddr;
key_t key;
key = ftok(".",1);
shmid = shmget(key,1024*4,IPC_CREAT|0666); // 可读可写
if(shmid == -1){ //判断是否成功,成功返回//指向共享内存的指针,失//败返回-1
printf("shmget error\n");
exit(-1);
}
shmaddr = shmat(shmid,0,0); //映射共享内存
printf("shmat ok\n");
strcpy(shmaddr,"Hello, welcome"); //映射成功后直接,把内容复制到该地址中
sleep(5); //睡眠5秒,让其他程序读
shmdt(shmaddr); //卸载共享内存
shmctl(shmid,IPC_RMID,0); //关掉共享内存
printf("quit\n");
return 0;
}
shmr.c
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
int main()
{
int shmid;
char *shmaddr;
key_t key;
key = ftok(".",1);
shmid = shmget(key,1024*4,0);//获取不创建设为0
if(shmid == -1){
printf("shmget error\n");
exit(-1);
}
shmaddr = shmat(shmid,0,0);
printf("shmat ok\n");
printf("data: %s\n",shmaddr); //直接读取
shmdt(shmaddr);
printf("quit\n");
return 0;
}