! https://zhuanlan.zhihu.com/p/145646723

学习网络上某一专栏的记录。非入门教材,不会事无巨细的写,所以阅读前最好有一定Linux编程基础和了解。

C几乎可以达到随意玩弄内存的目的。不信你看mmap

Linux I/O

Linux下的I/O方式有标准I/O,直接I/O,mmap。mmap可以优化文件I/O。

Linux 系统编程学习总结 (九)内存映射 - 图1

标准I/O,是通过系统调用read, write实现的,需要2次拷贝。第一次从磁盘把数据移到内核缓存区,第二次从内核缓存区移到用户态缓存区。

而mmap,优化了2点:

  1. 通过逻辑地址直接操作文件数据,避免read, write调用
  2. mmap中申明了映射的逻辑地址,那么中断处理函数就能知道把硬盘上的数据往哪里移。直接移到用户态内存,只需1次拷贝。

和fread,fwrite的对比

评论区有人问,写写。

我认为fread/fwrite和read/write没有本质区别,前者只是做了应用层的缓存优化。也就是说它们都属于标准I/O,避免不了syscall。而mmap,本质上是把内核+用户2个内存区缩短为一个而已,所以和fread/fwrite是完全不同的。

mmap更低级,更接近底层。有个答案这么说:fread每次都要走int0x80来进行system call(可是不是已经被废除了吗),而mmap完全是memory manipulation,不需要切换。而且mmap用了demand paging,程序没有真正用数据计算的时候,page不会加载进内存。

基于性能做选择的话,看场景。fread适用于小文件,mmap适用于大文件。没有绝对的更好。
(刚好有人问过这个:https://www.researchgate.net/post/What_is_the_actual_difference_between_fread_and_mmap_functions_in_linux_unix
摘抄一些好的)

Hmmm…well fread reads data from a device in an amount you specify from an open file descriptor. There are cacheing aspects to fread, or their can be.
mmap of course “maps” the file into memory. On most OS’s no data is actually read until the user tries to access it. On most OS’s the latest page accessed will be cached in memory and perhaps all the pages read will be.
Which one works “best” in your situation depends on ……well your situation. How many other processes are running. Are they also accessing the disk? If you are reading the data in, why wouldn’t you cache it in memory instead of re-reading?
Usually , your application will dictate which is better.
For instance - if you are loading code that will be accessed or linked with other application code - mmap would be best.

If you use fread(), there will always be overhead from the system call API (int 80, trapping into kernel space) while the mmap() let you set up once of the page table mapping for the file content and all the subsequent memory operation is done without trapping into kernel space.
Of course, when the disk block is accessed for the first time, it has to be populated into page cache, and this is the price that both fread() and mmap() need to pay.
Thus, if you need to repeatedly access the same file content, then mmap() will work better under the condition that your page cache is large enough to hold the content that you are accessing.

玩内存

Linux 提供很多接口可以玩内存,比如mprotect改权限,mlock锁住内存。

锁住内存,就是让某一些数据页一直待在内存里,不被LRU换进swap space。是为了性能考虑,但是真正用的很多的内存也不太需要考虑这点吧?所以看起来像是没什么用的api,逃)