簡體   English   中英

使用 fork 后 mmap 是否會導致頁面錯誤?

[英]Does mmap causes a page fault after we use fork?

由於 COW,linux 將僅在已寫入頁面后將其分配給子進程。 它還只會在更改后為堆棧分配一個新頁面。 因此,例如,如果在fork()系統調用之后,我們在子進程中調用 printf,由於堆棧已更改,我們將出現頁面錯誤。

但是我不確定以下代碼:

fork();
char *arr = mmap(... some args.. MAP_FILED|MAP_PRIVATE);

由於父子都運行 mmap,我假設第二行會發生頁面錯誤,因為我們調用了一個函數(實際上是系統調用)並創建了一個局部變量,從而改變了堆棧。 這樣對嗎?

特爾;博士:

我們 fork 后 mmap 是否會導致頁面錯誤?

調用mmap()或任何函數都會導致堆棧上的頁面錯誤,因為它需要將返回地址保存在堆棧上,然后為被調用的函數創建一個新的堆棧幀。

即使是對局部變量的賦值也會在沒有函數調用的情況下導致頁面錯誤。 所以簡單地做:

fork();
char *arr = NULL;

可能會導致頁面錯誤(我說“可能”是因為編譯器可能會優化它以在函數調用之前初始化內存一次;此外, arr變量可以存儲在寄存器中而不是內存中)。

大多數使用fork()代碼將返回值保存在一個變量中,因此它知道它是在父變量中還是在子變量中。 所以通常只要fork()返回就會出現頁面錯誤(同樣,除非該變量使用了寄存器)。

在所有這些情況下,只會在父進程或子進程中出現錯誤,而不是兩者都有。 第一個修改堆棧幀進行復制,然后清除 COW 標志,以便其他進程可以繼續使用原始頁面。

頁面錯誤發生mmap返回之后,並且您開始使用分配的段。 在此之前,內核會檢查錯誤,並將資源分配給您(以管理方式),但在您發出實際請求之前,它實際上不會將它們分配給您(這是當您通過讀取或寫入訪問內存本身時)內存)這遵循延遲初始化的技術,它使進程的啟動成為一個更平滑的任務,並且不會不必要地分配最終未被進程使用的資源。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM