共享内存的使用实现原理(必考必问,然后共享内存段被映射进进程空间之后,存在于进程空间的什么位置?共享内存段最大限制是多少?)
参考文章
Linux环境下C编程指南
引文
共享内存是进程间通信的一种最基本、最快速的机制。共享内存是两个或者多个进程共享同一块内存区域,并通过该内存区域实现数据交换的进程间通信机制。通常是由一个进程开辟一块共享内存区域,然后允许多个进程对此其区域进行访问。由于不需要使用中间介质,而是数据由内存直接映射到进程空间,因此共享内存是最快速的进程间通信机制。
每个共享内存区域对应特殊文件系统shm中的一个文件。
注:shmget的内部实现包含了许多重要的system V共享内存机制;shmat在把共享内存区域映射到进程空间时,并不真正改变进程的页表。当进程第一次访问内存映射区域访问时,会因为没有物理页表的分配而导致一个缺页异常,然后内核再根据相应的存储管理机制为共享内存映射区域分配相应的页表。
通过shmat将这个内存区映射到本进程的虚拟地址空间。
在 /proc/sys/kernel/
目录下,记录着系统V共享内存的限制,如一个共享内存区的最大字节数shmmax,系统范围内最大共享内存区标识符数shmmni等,可以手工对其调整,但不推荐这样做。
代码
writeshm.c往共享内存写
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUF_SIZE 1024
#define MYKEY 24
int main()
{
int shmid;
char *shmptr;
if ((shmid = shmget(MYKEY, BUF_SIZE, IPC_CREAT)) == -1)
{
printf("shmget error\n");
exit(1);
}
printf("shmid = %d\n", shmid);
if ((shmptr = shmat(shmid, 0, 0)) == (void*)-1)
{
printf("shmat error\n");
exit(1);
}
printf("origin shmptr = %p\n", shmptr);
while(1)
{
scanf("%s", shmptr);
//printf("shmptr addr = %p, shmptr = %s\n", shmptr, shmptr);
//sleep(3);
}
exit(0);
}
readshm.c从共享内存读
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#define BUF_SIZE 1024
#define MYKEY 24
int main()
{
int shmid;
char *shmptr;
if ((shmid=shmget(MYKEY, BUF_SIZE, IPC_CREAT)) == -1)
{
printf("shmget error\n");
exit(1);
}
printf("shmid = %d\n", shmid);
if ((shmptr = shmat(shmid, 0, 0)) == (void*)-1)
{
printf("shmat error\n");
}
while (1)
{
printf("string:%s\n", shmptr);
sleep(3);
}
exit(0);
}