linux中mmap()函数的内存映射问题理解?

oyffffff 2016-07-05 10:01:30
mmap()这个函数到底是把 硬盘里的数据映射到物理内存(还是虚拟内存?)中,还是把物理内存中的数据映射到虚拟内存中? 有点晕,我猜测是前者,但不确定。。。

还有,网上说的映射到多个页上是什么意思?物理内存不是连续的么,直接把硬盘上的数据dump到物理内存不就行了。

mmap()的好处一个是节约IO读写时间?(但是,内存映射了之后,最后我要保存的话还是需要把内存上的数据写到硬盘的吧?),还有一个是可以实现共享内存通信是吧?没别的好处了吧?

初次接触,查了资料还是有点晕,所以问题有点多,望各位大神谅解~
...全文
420 19 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
xmayyang 2016-07-15
  • 打赏
  • 举报
回复
原理: 这里主要是指硬盘上文件的位置与进程逻辑地址空间中一块大小相同的区域之间的一一对应。在内存映射的过程中,并没有实际的数据拷贝,文件没有被载入内存,只是逻辑上被放入了内存。 函数mmap()会返回一个指针p,这样以后读写文件,就不用调用read和write了,直接操作指针就可以了。但是指针p指向的逻辑地址,物理上不存在的,当进程的逻辑地址通过MMU向物理地址转换的时候,会造成失败(当然会失败了,本来就没有物理地址)。此时,MMU会产生一个缺页中断,中断响应函数会将硬盘上的文件读到内存中来。 好处: mmap的好处是比read、write这样的系统调用或者fread、fwrite这样的c库函数要快3倍以上。原因是,系统调用读写文件要经过内核空间,c库函数还要先过自己的缓存,再过内核空间,然后才能到进程的用户空间,所以会慢很多
mrliu_qy 2016-07-12
  • 打赏
  • 举报
回复
void* mmap(void* start,size_t length,int prot,int flags,int fd,off_t offset); 找个函数原型来解释一下 mmap()这个函数到底是把 硬盘里的数据映射到物理内存(还是虚拟内存?)中,还是把物理内存中的数据映射到虚拟内存中? 有点晕,我猜测是前者,但不确定。。。 首先。如果是硬盘里的数据话的是映射到虚拟内存中的。。。但是,mmap也是可以把物理内存直接映射到虚拟内存中。把fd改为-1 还有,网上说的映射到多个页上是什么意思?物理内存不是连续的么,直接把硬盘上的数据dump到物理内存不就行了。 这句多个页我也没理解清楚是干嘛用的。 mmap()的好处一个是节约IO读写时间?(但是,内存映射了之后,最后我要保存的话还是需要把内存上的数据写到硬盘的吧?),还有一个是可以实现共享内存通信是吧?没别的好处了吧? mmap实际用处是很大的,不单止是用来共享内存通信,你能想象malloc是调用它来实现,malloc能做的事它都能做。mmap很强大的说
ec06cumt 2016-07-12
  • 打赏
  • 举报
回复
引用 16 楼 ddj11223 的回复:
引用 14 楼 ec06cumt 的回复:
共享内存通信,一般可以做两块共享内存,一个读一个写就好了,这样就可以不考虑多个两个进程读写的同步问题。。。
但是这样的话,一个进程往里写的数据,另外一个进程还是读不到啊
你的这两个共享内存都要映射成文件,然后两个进程分别读写,同一个映射共享内存的映射文件。。。一个进程对应写,另一个进程对应读,同一个共享内存。。。这样就OK了。。。
oyffffff 2016-07-10
  • 打赏
  • 举报
回复
引用 14 楼 ec06cumt 的回复:
共享内存通信,一般可以做两块共享内存,一个读一个写就好了,这样就可以不考虑多个两个进程读写的同步问题。。。
但是这样的话,一个进程往里写的数据,另外一个进程还是读不到啊
renwotao2009 2016-07-09
  • 打赏
  • 举报
回复
建议可以看下Unix高级环境编程
oyffffff 2016-07-08
  • 打赏
  • 举报
回复
引用 12 楼 lsshao 的回复:
两个进程各自打开和映射相同的文件,共享文件方式,可以实现两个进程的通信,但是需要注意同步和缓存。
我在想一个问题,你说两个进程各自打开相同的文件,那会不会把这个文件放到物理内存两次啊,它是做到如何识别并只放一次的呢
Kyph 2016-07-08
  • 打赏
  • 举报
回复
两个进程各自打开和映射相同的文件,共享文件方式,可以实现两个进程的通信,但是需要注意同步和缓存。
ec06cumt 2016-07-08
  • 打赏
  • 举报
回复
共享内存通信,一般可以做两块共享内存,一个读一个写就好了,这样就可以不考虑多个两个进程读写的同步问题。。。
oyffffff 2016-07-07
  • 打赏
  • 举报
回复
引用 10 楼 lsshao 的回复:
进程的内存共享,有专门的机制。 不能采用直接传虚地址方式,因为每个进程的页表都是独有的,只有专门的内存共享IPC,才能保证给两个进程映射的物理内存相同。
所以mmap()就可以完成这件事情对吧
Kyph 2016-07-07
  • 打赏
  • 举报
回复
进程的内存共享,有专门的机制。 不能采用直接传虚地址方式,因为每个进程的页表都是独有的,只有专门的内存共享IPC,才能保证给两个进程映射的物理内存相同。
renwotao2009 2016-07-06
  • 打赏
  • 举报
回复
把硬盘文件映射到不同进程虚拟内存空间中,进程间可以直接读写此虚拟空间地址进行通信
oyffffff 2016-07-06
  • 打赏
  • 举报
回复
引用 1 楼 renwotao2009 的回复:
把硬盘文件映射到不同进程虚拟内存空间中,进程间可以直接读写此虚拟空间地址进行通信
也就是说,如果有两个进程,需要用mmap来实现共享内存通信,是不是每个进程都要调用一次mmap,那如果让第一个进程调用一次mmap,得到的虚存addr和length,直接传给第二个进程,实现共享内存通信,这样可以吗?
oyffffff 2016-07-06
  • 打赏
  • 举报
回复
引用 8 楼 renwotao2009 的回复:
[quote=引用 7 楼 ddj11223 的回复:] [quote=引用 3 楼 lsshao 的回复:] 把物理内存中的数据映射到虚拟内存中 直接传是不行的
两个进程公用一个虚拟地址?不同的进程其虚拟地址一样但可能物理地址不一样吧?[/quote]物理地址一样,虚拟地址可能不一样[/quote]嗯,那这样就说得通了
renwotao2009 2016-07-06
  • 打赏
  • 举报
回复
引用 7 楼 ddj11223 的回复:
[quote=引用 3 楼 lsshao 的回复:] 把物理内存中的数据映射到虚拟内存中 直接传是不行的
两个进程公用一个虚拟地址?不同的进程其虚拟地址一样但可能物理地址不一样吧?[/quote]物理地址一样,虚拟地址可能不一样
oyffffff 2016-07-06
  • 打赏
  • 举报
回复
引用 3 楼 lsshao 的回复:
把物理内存中的数据映射到虚拟内存中 直接传是不行的
两个进程公用一个虚拟地址?不同的进程其虚拟地址一样但可能物理地址不一样吧?
oyffffff 2016-07-06
  • 打赏
  • 举报
回复
引用 5 楼 renwotao2009 的回复:
引用 2 楼 ddj11223 的回复:
引用 1 楼 renwotao2009 的回复:
把硬盘文件映射到不同进程虚拟内存空间中,进程间可以直接读写此虚拟空间地址进行通信
也就是说,如果有两个进程,需要用mmap来实现共享内存通信,是不是每个进程都要调用一次mmap,那如果让第一个进程调用一次mmap,得到的虚存addr和length,直接传给第二个进程,实现共享内存通信,这样可以吗?
不是直接传递虚存的地址,而是两个进程一个读一个写这个虚拟地址进行通信
难道两个进程公用一个虚拟地址?不同的进程其虚拟地址一样但可能物理地址不一样吧?
renwotao2009 2016-07-06
  • 打赏
  • 举报
回复
引用 2 楼 ddj11223 的回复:
引用 1 楼 renwotao2009 的回复:
把硬盘文件映射到不同进程虚拟内存空间中,进程间可以直接读写此虚拟空间地址进行通信
也就是说,如果有两个进程,需要用mmap来实现共享内存通信,是不是每个进程都要调用一次mmap,那如果让第一个进程调用一次mmap,得到的虚存addr和length,直接传给第二个进程,实现共享内存通信,这样可以吗?
不是直接传递虚存的地址,而是两个进程一个读一个写这个虚拟地址进行通信
apple_v1 2016-07-06
  • 打赏
  • 举报
回复
mmap将文件映射到当前当前进程的虚拟内存中,如果地址指定为空则由内核分配,文件偏移量大小必须为页大小的整数倍(为了根据偏移量快速计算页)。将文件高速缓存后可以减少不必要的磁盘I/O,减少文件访问时间。
Kyph 2016-07-06
  • 打赏
  • 举报
回复
把物理内存中的数据映射到虚拟内存中 直接传是不行的

23,215

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧