一直在为找大三的实习做准备,很长一段时间都没有更新我的CSDN了,期间主要就是画思维导图来实现构建知识体系,思维导图的链接:https://gitee.com/lemaliu/my_computer_knowledge_system,现在终于有时间安心静下来好好沉淀沉淀了。
经过这段时间的面试,发现共享内存被问的频率虽然不高,但一直对它没有一个深刻的理解,认为就是Linux下进程间通信的一种方式,仅仅写过简单的代码(进程通信,一问一答等),现在对共享内存进行一个比较深入的学习,接下来从以下几个方面来重新探寻一下共享内存。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
目录
什么是共享内存为什么共享内存是最快的进程间通信方式
什么是共享内存?
在wiki百科中,共享内存分为硬件层面和软件层面的理解,这篇博客仅探究共享内存的软件层面。
进程间通信的方式中,共享内存的速度是最快的,因为管道,消息队列等在进行进程间通信的时候需要进行多次的用户空间到内核空间的切换,而共享内存不需要将数据频繁地在用户态和内核态进行拷贝。
下图为管道,消息队列的数据传递示意图
看到管道,消息队列等进行进程间通信的时候,需要不停在用户态和内核太之间进行数据的复制和状态的切换,下图来看看共享内存的数据流向图
可以看到,共享内存在传输数据的时候,都是在用户态进行的,当两个进行映射到同一块共享地址空间的时候,往共享内存中写入,读取都是用户态的操作了,也就节约了大量的时间。
共享内存的基本使用方法简单演示
使用Linux的系统调用接口,实现一个wshm.c向共享内存中写数据,然后实现一个rshm.c向共享内存中将其写入的数据读出来。
代码链接:https://gitee.com/lemaliu/blog_material_codes/tree/master/IPC/shared_memory/simple
具体代码:
/*
* file-name: wshm.c
*
* date: 2019-4-5
*
* desc: IPC shared memory
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
//create IPC key
key_t key = ftok("./", 66);
int* pp = NULL;
void* addr = NULL;
//create shared memory, return an ID
int shmid = shmget(key, 100, IPC_CREAT|IPC_EXCL|0666);
if(shmid == -1)
{
perror("shmget");
return 1;
}
//detach the shared memory
addr = shmat(shmid, 0, 0);
if((void *)-1 == addr)
{
perror("shmat");
return 1;
}
//write to shared memory
pp = (int*)addr;
*pp = 0x12312312;
*(pp + 1) = 0x6fffffff;
//destory detach
if(-1 == shmdt(addr))
{
perror("shmdt");
return 1;
}
printf("shmdt is successful\n");
getchar();
//delete shared memory
if(-1 == shmctl(shmid, IPC_RMID, NULL))
{
perror("shmctl");
return 1;
}
return 0;
}
/*
* file-name: rshm.c
*
* date: 2019-4-5
*
* desc: IPC shared memory
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
int main()
{
//create IPC key
key_t key = ftok("./", 66);
int* pp = NULL;
void* addr = NULL;
//create shared memory, return an ID
int shmid = shmget(key, 0, 0);
if(shmid == -1)
{
perror("shmget");
return 1;
}
//detach the shared memory
addr = shmat(shmid, 0, 0);
if((void *)-1 == addr)
{
perror("shmat");
return 1;
}
//read to shared memory
pp = (int*)addr;
int x = *(int*)pp;
int y = *((int*)pp + 1);
printf("read from shared memroy : 0x%x, 0x%x\n", x, y);
//destory detach
if(-1 == shmdt(addr))
{
perror("shmdt");
return 1;
}
printf("shmdt is successful\n");
getchar();
//delete shared memory
if(-1 == shmctl(shmid, IPC_RMID, NULL))
{
perror("shmctl");
return 1;
}
return 0;
}
上述代码运行起来,会在rshm从共享内存读到数据。