你真的知道匿名映射是什麼嗎?

《認真分析mmap:是什麼 爲什麼 怎麼用》中提到了匿名映射,只要在 flags 參數中增加 MAP_ANONYMOUS,即爲匿名映射。此時,會忽略參數 fd,映射區不與任何文件關聯,而且映射區域無法和其他進程共享。

根據 mmap 映射是否與文件相關聯,可以將 Linux 內核中映射可以分爲兩種:匿名映射和文件映射。

  • 匿名映射:沒有映射對應的相關文件,這種映射的內存區域的內容會被初始化爲0。
  • 文件映射:映射和實際文件相關聯,通常是把文件的內容映射到進程地址空間,這樣應用程序就可以像操作進程地址空間一樣讀寫文件。

根據文件關聯性、映射區域是否共享這兩個屬性,mmap的映射類型,又可以分爲如下4種:

私有映射 共享映射
匿名映射 私有匿名映射 - 通常用於內存分配 共享匿名映射 - 通常用於進程間共享內存
文件映射 私有文件映射 - 通常用於加載動態庫 共享文件映射 - 通常用於內存映射IO,進程間通信
  1. 私有匿名映射
    當使用參數 fd=-1 且 flags=MAP_ANONYMOUS | MAP_PRIVATE 時,創建的 mmap 映射是私有匿名映射。私有匿名映射最常見的用途是在 glibc 分配大塊內存中,當需要的分配的內存大於 MMAP_THREASHOLD(128KB) 時,glibc會默認使用 mmap 代替 brk 來分配內存。

  2. 共享匿名映射
    當使用參數 fd=-1 且 flags=MAP_ANONYMOUS | MAP_SHARED 時,創建的 mmap 映射是共享匿名映射。共享匿名映射讓相關進程共享一塊內存區域,通常用於父子進程的之間通信。

    創建共享匿名映射有如下兩種方式:

    • fd=-1 且 flags= MAP_ANONYMOUS|MAP_SHARED。在這種情況下,do_mmap_pgoff()->mmap() 函數最終調用 shmem_zero_setup() 來打開一個 "/dev/zero" 特殊的設備文件。
    • 直接打開 "/dev/zero" 設備文件,然後使用這個文件句柄來創建 mmap。
  3. 私有文件映射
    私有文件映射時 flags 的標誌位被設置爲 MAP_PRIVATE,那麼就會創建私有文件映射。私有文件映射的最常用的場景是加載動態共享庫。

  4. 共享文件映射
    創建文件映射時 flags 的標誌位被設置爲 MAP_SHARED,那麼就會創建共享文件映射。如果 prot 參數指定了 PROT_WRITE,那麼打開文件需要制定 O_RDWR 標誌位。

    共享文件映射通常有如下場景:

    • 讀寫文件:
      把文件內容映射到進程地址空間,同時對映射的內容做了修改,內核的回寫機制(writeback)最終會把修改的內容同步到磁盤中。
    • 進程間通信:
      進程之間的進程地址空間相互隔離,一個進程不能訪問到另外一個進程的地址空間。如果多個進程都同時映射到一個相同的文件,就實現了多進程間的共享內存的通信。如果一個進程對映射內容做了修改,那麼另外的進程是可以看到的。

作者:yooooooo
鏈接:https://www.cnblogs.com/linhaostudy/p/13467118.html
來源:博客園
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章