歡迎光臨
每天分享高質量文章

宋寶華: Linux mmap的多種情況和背後的差異

我們都知道,Linux一個行程使用的記憶體分為2種:

  1. file-backed pages(有檔案背景的頁面,比如程式碼段、比如read/write方法讀寫的檔案、比如mmap讀寫的檔案;他們有對應的硬碟檔案,因此如果要交換,可以直接和硬碟對應的檔案進行交換),此部分頁面進page cache

  2. anonymous pages(匿名頁,如stack,heap,CoW後的資料段等;他們沒有對應的硬碟檔案,因此如果要交換,只能交換到虛擬記憶體-swapfile或者Linux的swap硬碟分割槽),此部分頁面,如果系統記憶體不充分,可以被swap到swapfile或者硬碟的swap分割槽


下麵我們看看,mmap的各種情況,與上面的頁面型別之間的關係。


  1. 不對映任何檔案(MAP_ANONYMOUS),又分為私有和共享對映2種情況:

    1.1 私有對映(MAP_PRIVATE)

    這個是malloc庫函式之類底層的實現之一,最後對應匿名頁。

    比如應用程式呼叫:

    int *p= malloc(1024*1024*80);
    對應的系統呼叫是:

    mmap2(NULL, 83890176, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)

    1.2 共享對映MAP_SHARED

    用作有親緣關係行程間的共享記憶體通訊,最後對應匿名頁。


  2. 對映磁碟裡面的檔案,又分為共享對映和私有對映

    2.1 共享對映: 這個時候頁面dirty後要回寫磁碟,是有檔案背景(file-backed)的頁面

    2.2 私有對映:這個時候是CoW(寫時複製)頁面,最後變成匿名頁


  3. 對映tmpfs檔案,一般做行程間共享記憶體通訊用(不需要親緣關係),以共享方式對映,看起來是類似2.1有file-backed,但是file本身也是記憶體,所以本質上面還是匿名頁,程式碼實體:



  4. 對映framebuffer等,視訊記憶體,多媒體,這些是為了減少一次使用者空間往核心空間的記憶體複製。這個時候mmap對應的檔案是/dev/下麵的裝置檔案。程式碼案例:

int fb;
unsigned char* fb_mem;
fb = open (“/dev/fb0”, O_RDWR);
fb_mem = mmap (NULL, 1024*768, PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);
memset (fb_mem, 0, 1024*768 );

內容轉載自公眾號:Linuxer

贊(0)

分享創造快樂