概述
目录
基本概念
相关系统调用
使用内存映射进程通信:(是非阻塞通信。)
父子进程通过内存映射通信;
内存映射注意事项
匿名映射
基本概念
将磁盘文件映射到内存,用户修改内存就可以直接修改磁盘文件。(修改内存快很多,改磁盘很慢)。
相关系统调用
void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
映射长length(非0)的磁盘文件到addr(nullptr则自动选择一个)。
stat lseek可以获取文件长度(当小于分页大小,会至少指定一个分页大小)
prot:对申请的内存映射区的操作权限。 PROT_EXEC PROT_WRITE PROT_READ PROT_NONE 要操作,必须有读的权限
flags:MAP_SHARED 映射区数据会自动和磁盘文件同步,进程通信必须设置
MAP_PRIVATE 不同步,映射区修改后,创建一个新文件
fd:open()得到的映射文件的fd,大小不能为0. open指定权限与prot不能冲突
offset:偏移量,必须是4k的整数倍,一般不偏移,置0.、
成功返回创建的内存的首地址 失败返回MAP_FAILED (void*) -1;
int munmap(void *addr, size_t length); 释放内存映射 数值同上。
使用内存映射进程通信:(是非阻塞通信。)
1 有关系的进程: 先映射,再fork() 父子进程共享创建的内存映射区
2 没有关系:准备一个大小非0的磁盘文件,
进程1以此创建内存映射区,得到操作该内存的指针,
进程2也以此创建内存映射区,得到操作该内存的指针, 两个以此通信。
父子进程通过内存映射通信;
#include <sys/mman.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <cstring>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
int main()
{
int ret=open("test.txt",O_RDWR);
int size=lseek(ret,0,SEEK_END);
//内存映射
void* ptr=mmap(nullptr,size,PROT_READ|PROT_WRITE,MAP_SHARED,ret,0);
if(ptr==MAP_FAILED)
{
perror("mmap:");
exit(0);
}
pid_t pid=fork();
if(pid>0)
{//父进程
wait(NULL);
char buf[64];
strcpy(buf,(char*)ptr);
std::cout<<"parent read: "<<buf<<" "<<getpid()<<std::endl;
}
else if(pid==0)
{
//子进程
strcpy((char*)ptr,"today is a good day");
}
std::cout<<"i am here "<<getpid()<<"n";
munmap(ptr,size);
}
内存映射注意事项
1 mmap返回的ptr,可以++,但是++后munmap(ptr,len)会发生错误。 所以++前要先保存一份。
2 open指定权限与prot不能冲突,MAP_FAILED
3 文件偏移量必须是4k整数倍,否则返回MAP_FAILED
4 磁盘文件大小非0
5 open时可以O_CREAT创建新文件,但为了文件大小非0,需要对其扩展,lseek/ftruncate。
int ret=open("lseek.txt",O_CREAT|O_RDWR,0664);
lseek(ret,20,SEEK_END);
char *wrbuf= "hjhk";
write(ret,wrbuf,strlen(wrbuf)); 扩展并写入文件大小才能生效
或者//
ftruncate(ret,20);
//truncate("lseek.txt",20)
6 mmap后关闭fd,对mmap无影响。
7 void*ptr=mmap() ptr越界操作的时非法内存,会产生段错误(当程序试图访问不允许访问内存位置,或试图以不允许的方式访问内存位置(例如尝试写入只读位置,或覆盖部分操作系统)时会发生段错误)。
8 可以用来实现文件复制。旧文件和要复制的文件分别映射后, memcpy(ptr1,ptr,len)进行内存复制。
匿名映射
不需要文件实体进行内存映射。可用于父子进程通信。 flag设置MAP_ANONYMOUS fd=-1;
void* ptr=mmap(nullptr,4096,PROT_READ|PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1,0);
最后
以上就是自由蛋挞为你收集整理的进程间通信:内存映射基本概念相关系统调用使用内存映射进程通信:(是非阻塞通信。)父子进程通过内存映射通信;内存映射注意事项匿名映射的全部内容,希望文章能够帮你解决进程间通信:内存映射基本概念相关系统调用使用内存映射进程通信:(是非阻塞通信。)父子进程通过内存映射通信;内存映射注意事项匿名映射所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复