#include <stdio.h>
#include <sys/mman.h>
/*
mmap,将文件映射到内存当中
void *addr: 要映射到的地址,直接使用NULL,不用我们自己指定,让操作系统内核指定即可
返回值是创建映射的内存地址
length:要映射的数据的长度,据此确定申请的内存空间,且不可为0
可以使用stat获取文件长度,lseek函数也可以
prot:对申请的内存区域的权限,读、写、执行、NONE(啥权限都没有,这有啥用?)
flags: MAP_SHARED、MAP_PRIVATE
前者表示映射区的内容和硬盘中的文件会同步
后者表示不同步,内存区的内容变了之后,会创建一个新的文件
fd:需要映射的文件描述符,使用open函数获取,且文件大小不可为0
且open函数指定的权限不能和prot指定的权限有冲突,两者需要保持一致,prot权限一定要是open设置的
权限的子集
offset:文件的偏移量,一般不用,必须是4k的整数倍,0表示不偏移
munmap:
用于释放文件在内存中的映射
addr:要释放的内存地址
length:要释放的内存大小
*/
/*
使用内存映射实现进程间通信
1、有关系的进程(父子进程)
还没有子进程的时候:
父进程需要先创建内存映射
有了内存映射区之后,子进程就可以创建了
父子进程共享内存映射区
2、没有关系的进程
准备一个大小不为0的文件
进程1通过磁盘文件创建内存映射区
得到一个指针
进程2通过磁盘文件创建一个内存映射区
得到一个指针
使用内存映射区进行进程间通信
内存映射区通信是非阻塞的
*/
#include<stdlib.h>
#include<wait.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main()
{
//打开一个文件
int fd = open("1.c", O_RDWR);
//获取文件大小
int size = lseek(fd, 0, SEEK_END);
//创建内存映射区
void *ptr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED)
{
perror("mmap");
exit(0);
}
//创建子进程
pid_t pid = fork();
if (pid > 0)
{
wait(NULL);
char buf[1024] = {0};
strcpy(buf, (char *)ptr);
printf("收到的数据: %s\n", buf);
}
else if (0 == pid)
{
strcpy((char *)ptr, "cao ni ma, er zi!!!");
}
//关闭内存映射区
munmap(ptr, size);
return 0;
}
可以看到内容被写到了文件中