日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

OS - MMAP初探

發布時間:2025/3/21 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OS - MMAP初探 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 生猛干貨
  • What's mmap
  • mmap 函數
  • mmap() 的底層原理
    • 虛擬內存空間與物理內存空間
    • vm_area_struct 結構
    • 對文件的讀寫
  • 搞定計算機基礎內功

生猛干貨

計算機專業學生、非科班程序員必備! 90%程序員忽略的大廠招聘考點、技能進階秘訣盡在這里!


What’s mmap

https://man7.org/linux/man-pages/man2/mmap.2.html

簡單來說: mmap() 系統調用能夠將文件映射到內存空間,然后可以通過讀寫內存來讀寫文件


mmap 函數

#include <sys/mman.h>void *mmap(void *addr, size_t length, int prot, int flags,int fd, off_t offset);
  • start:指定要映射的內存地址,一般設置為 NULL 讓操作系統自動選擇合適的內存地址。
  • length:映射地址空間的字節數,它從被映射文件開頭 offset 個字節開始算起。
  • prot:指定共享內存的訪問權限。可取如下幾個值的可選:PROT_READ(可讀), PROT_WRITE(可寫), PROT_EXEC(可執行), PROT_NONE(不可訪問)。
  • flags:由以下幾個常值指定:MAP_SHARED(共享的) MAP_PRIVATE(私有的), - MAP_FIXED(表示必須使用 start 參數作為開始地址,如果失敗不進行修正),其中,MAP_SHARED , MAP_PRIVATE必選其一,而 MAP_FIXED 則不推薦使用。
  • fd:表示要映射的文件句柄。
  • offset:表示映射文件的偏移量,一般設置為 0 表示從文件頭部開始映射。

函數的返回值為最后文件映射到進程空間的地址,進程可直接操作起始地址為該值的有效地址。

舉個例子

int main() {...fd = open(name, flag, mode);if (fd < 0) {// error process...exit(1);}addr = mmap(NULL, len, PROT_READ|PROT_WRITE|PROT_EXEC, MAP_SHARED, fd, 0);if (addr < 0) {// error process...exit(1);}memset(addr, 0, len);...exit(0); }

首先通過 open() 系統調用打開一個文件,然后通過調用 mmap() 把文件映射到內存空間,映射成功后就可以通過操作函數返回的內存地址來對文件進行讀寫操作


mmap() 的底層原理

虛擬內存空間與物理內存空間

我們先來看下 操作系統的虛擬內存空間物理內存空間的概念 。

在 32位的 Linux 內核中,每個進程都獨有 4GB 的虛擬內存空間,但所有進程卻共用相同的物理內存空間。

物理內存空間就是安裝在電腦上的內存條,如果內存條只有 1GB,那么物理內存空間就只有 1GB。但虛擬內存空間是邏輯上的內存空間,虛擬內存空間必須映射到物理內存空間才能使用

虛擬內存空間與物理內存空間映射關系如下:

映射是按內存頁進行的,一個內存頁為 4KB 大小。

在上圖中,P1 是進程1,P2 是進程2。

  • 進程1的虛擬內存頁A映射到物理內存頁A
  • 進程2的虛擬內存頁A映射到物理內存頁B
  • 進程1的虛擬內存頁B和進程2的虛擬內存頁B同時映射到物理內存頁C,也就是說進程1和進程2共享了物理內存頁C

vm_area_struct 結構

在Linux內核中,虛擬內存是用過結構體 vm_area_struct 來管理的,通過 vm_area_struct 結構體可以把虛擬內存劃分為多個用途不相同的內存區,比如可以劃分為數據段區、代碼段區等等.

vm_area_struct

struct vm_area_struct { struct mm_struct * vm_mm; /* The address space we belong to. */ unsigned long vm_start; /* Our start address within vm_mm. */ unsigned long vm_end; /* The first byte after our end addresswithin vm_mm. *//* linked list of VM areas per task, sorted by address */ struct vm_area_struct *vm_next;pgprot_t vm_page_prot; /* Access permissions of this VMA. */ unsigned long vm_flags; /* Flags, listed below. */rb_node_t vm_rb;struct vm_area_struct *vm_next_share; struct vm_area_struct **vm_pprev_share;/* Function pointers to deal with this struct. */ struct vm_operations_struct * vm_ops; ... struct file * vm_file; /* File we map to (can be NULL). */ ... };

vm_area_struct 結構各個字段作用:

  • vm_mm:指向進程內存空間管理對象。
  • vm_start:內存區的開始地址。
  • vm_end:內存區的結束地址。
  • vm_next:用于連接進程的所有內存區。
  • vm_page_prot:指定內存區的訪問權限。
  • vm_flags:內存區的一些標志。
  • vm_file:指向映射的文件對象。
  • vm_ops:內存區的一些操作函數。

vm_area_struct 結構與虛擬內存地址的關系如下圖:


每個進程都由 task_struct 結構進行管理,task_struct 結構中的 mm 成員指向了每個進程的內存管理結構 mm_struct,而 mm_struct 結構的 mmap 成員記錄了進程虛擬內存空間各個內存區的 vm_area_struct 結構鏈表。

當調用 mmap() 時,內核會創建一個 vm_area_struct 結構,并且把 vm_start 和 vm_end 指向虛擬內存空間的某個內存區,并且把 vm_file 字段指向映射的文件對象。然后調用文件對象的 mmap 接口來對 vm_area_struct 結構的 vm_ops 成員進行初始化,如 ext2 文件系統的文件對象會調用 generic_file_mmap() 函數進行初始化,代碼如下:

static struct vm_operations_struct generic_file_vm_ops = { nopage: filemap_nopage, };int generic_file_mmap(struct file * file, struct vm_area_struct * vma) { struct address_space *mapping = file->f_dentry->d_inode->i_mapping; struct inode *inode = mapping->host;if ((vma->vm_flags & VM_SHARED) && (vma->vm_flags & VM_MAYWRITE)) { if (!mapping->a_ops->writepage) return -EINVAL; } if (!mapping->a_ops->readpage) return -ENOEXEC; UPDATE_ATIME(inode); vma->vm_ops = &generic_file_vm_ops; return 0; }

vm_operations_struct 結構的 nopage 接口會在訪問內存發生異常時被調用,上面指向的是 filemap_nopage() 函數,filemap_nopage() 函數的主要工作是:

  • 把映射到虛擬內存區的文件內容讀入到物理內存頁中。
  • 對訪問發生異常的虛擬內存地址與物理內存地址進行映射。
  • 處理過程如下


    如上圖所示,虛擬內存頁m 映射到 物理內存頁x,并且把映射的文件的內容讀入到物理內存中,這樣就把內存與文件的映射關系建立起來,對映射的內存區進行讀寫操作實際上就是對文件的讀寫操作。

    一般來說,對映射的內存空間進行讀寫并不會實時寫入到文件中,所以要對內存與文件進行同步時需要調用 msync() 函數來實現。


    對文件的讀寫

    像 read()/write() 這些系統調用,首先需要進行內核空間,然后把文件內容讀入到緩存中,然后再對緩存進行讀寫操作,最后由內核定時同步到文件中。過程如下圖:


    而調用 mmap() 系統調用對文件進行映射后,用戶對映射后的內存進行讀寫實際上是對文件緩存的讀寫,所以減少了一次系統調用,從而加速了對文件讀寫的效率。如下圖:


    搞定計算機基礎內功

    總結

    以上是生活随笔為你收集整理的OS - MMAP初探的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 亚洲 激情 小说 另类 欧美 | 欧美裸体xxxx极品少妇 | 九九久久国产视频 | 久久三级 | 好吊在线视频 | 古代黄色一级片 | 男人和女人搞鸡 | 中文字幕av免费观看 | 天堂网www| 免费看黄色片网站 | 美女隐私免费观看 | 国产精品成人一区二区三区电影毛片 | 欧美 日韩 国产 成人 在线 91 | 久精品免费视频 | 特黄特色大片免费 | 在线观看一区二区三区视频 | 国产女主播自拍 | 欧洲美女与动交ccoo | 亚洲黄色在线观看 | 欧美精品福利视频 | 亚洲另类天堂 | 亚欧在线免费观看 | 亚洲高清资源 | 国产乱子伦一区二区 | 大战熟女丰满人妻av | 国产成人精品一区二区在线观看 | 中文在线观看免费网站 | 91中文字幕网 | 日韩欧美中文字幕一区二区三区 | 国产福利短视频 | 国产高清黄色 | 福利小视频在线播放 | www.久操| 国产精品久久久久野外 | 91精品国产乱码久久久久 | 伊人一区二区三区四区 | 国产精品zjzjzj在线观看 | av最新网| 琪琪女色窝窝777777 | av资源网在线观看 | 国产精品网站在线 | 丁香五香天堂网 | 欧美在线影院 | 激情小说一区 | 美国一级大黄一片免费中文 | 国产对白视频 | 成人久久一区二区 | 小镇姑娘高清播放视频 | 国产一二三区av | 日本va欧美va欧美va精品 | 人妻体内射精一区二区 | 古代黄色片 | av88av| 四虎影院污 | 在线免费av播放 | 欧美xxxⅹ性欧美大片 | 又黄又爽的视频 | 免费看国产一级片 | 日韩在线观看视频网站 | 伊人网在线免费观看 | 久操久热 | 色淫湿视频 | 欧美xo影院 | 欧美日韩在线一区二区三区 | 免费看污片网站 | 男男做爰猛烈叫床爽爽小说 | 久热综合 | 色图自拍偷拍 | 欧美成人综合视频 | 久久黄色片 | 韩国无码一区二区三区精品 | 国产午夜精品一区 | 国产第一毛片 | 黄色片在线免费看 | 亚洲色图二区 | 亚洲天堂国产精品 | 日本高清有码 | 白丝美女被草 | 午夜成人亚洲理伦片在线观看 | 少妇被爽到高潮动态图 | 国产在线不卡一区 | 波多野结衣视频网址 | 亚洲在线免费观看视频 | 日本人jizz| 午夜中文字幕 | japansexxxxhd医生| 精品国产aⅴ | 男人和女人日批 | 大伊人网| 男人日女人在线观看 | 大奶子情人 | 91在线小视频| 中文在线亚洲 | 亚洲国产精品久久久久久久 | 中文无码精品一区二区三区 | 污污视频免费观看 | 免费一级特黄特色大片 | 欧美在线性| 国产精品美女久久久久久久 |