mlock家族:鎖定物理內存

mlock家族:鎖定物理內存

系統調用 mlock 家族容許程序在物理內存上鎖住它的部分或所有地址空間。這將阻止Linux 將這個內存頁調度到交換空間(swap space),即便該程序已有一段時間沒有訪問這段空間。安全

一個嚴格時間相關的程序可能會但願鎖住物理內存,由於內存頁面調出調入的時間延遲可能太長或過於不可預知。安全性要求較高的應用程序可能但願防止敏感數據被換出到交換文件中,由於這樣在程序結束後,攻擊者可能從交換文件中恢復出這些數據。app

鎖定一個內存區間只需簡單將指向區間開始的指針及區間長度做爲參數調用 mlockLinux 分配內存到頁(page)且每次只能鎖定整頁內存,被指定的區間涉及到的每一個內存頁都將被鎖定。getpagesize 函數返回系統的分頁大小,在 x86 Linux 系統上,這個值是 4KB。ide

舉個例子來講,分配 32Mb 的地址空間並把它鎖進內存中,您須要使用以下的代碼:函數

const int alloc_size = 32 * 1024 * 1024;
char* memory = malloc (alloc_size);
mlock (memory, alloc_size);

需注意的是,僅分配內存並調用 mlock 並不會爲調用進程鎖定這些內存,由於對應的分頁多是寫時複製(copy-on-write)5。所以,你應該在每一個頁面中寫入一個假的值:spa

size_t i;
size_t page_size = getpagesize ();
for (i = 0; i < alloc_size; i += page_size)
  memory[i] = 0;

這樣針對每一個內存分頁的寫入操做會強制 Linux 爲當前進程分配一個獨立、私有的內存頁。.net

要解除鎖定,能夠用一樣的參數調用 munlock。指針

若是你但願程序的所有地址空間被鎖定在物理內存中,請用 mlockall。這個系統調用接受一個參數;若是指定 MCL_CURRENT,則僅僅當前已分配的內存會被鎖定,以後分配的內存則不會;MCL_FUTURE 則會鎖定以後分配的全部內存。使用 MCL_CURRENT|MCL_FUTURE 將已經及未來分配的全部內存鎖定在物理內存中。進程

鎖定大量的內存,尤爲是經過 mlockall,對整個系統而言多是危險的。不加選擇的內存加鎖會把您的系統折磨到死機,由於其他進程被迫爭奪更少的資源的使用權,而且會更快地被交換進出物理內存(這被稱之爲 thrashing)。若是你鎖定了太多的內存,Linux 系統將總體缺少必需的內存空間並開始殺死進程。ip

出於這個緣由,只有具備超級用戶權限的進程才能利用 mlock 或 mlockall 鎖定內存。若是一個並沒有超級用戶權限的進程調用了這些系統調用將會失敗、獲得返回值 -1 並獲得 errno 錯誤號 EPERM。內存

munlock 系統調用會將當前進程鎖定的全部內存解鎖,包括經由 mlock 或 mlockall 鎖定的全部區間。

一個監視程序內存使用狀況的方便方法是使用top命令。在top的輸出中,SIZE顯示了每一個程序的虛地址空間的大小(您的整個程序代碼、數據、棧,其中 一些應該已被交換出到交換區間)。RSS 列(Resident set size,持久集合大小)顯示了程序所佔用的的物理內存大小。全部當前運行程序的 RSS 數值總和不會超過您的計算機物理內存大小,而且全部地址空間的大小限制值爲2GB(對於32字節版本的Linux來講)

若是您使用了mlock系統調用,請引入<sys.nman.h>頭文件。

5 Copy-on-write 寫時複製意味着僅當進程在內存區間的任意位置寫入內容時,Linux 系統纔會爲進程建立該區內存的私有副本。

相關文章
相關標籤/搜索