2012-07-04 62 views
4

假設我在Linux上有兩個進程ab。並且在這兩個過程中我使用malloc()來分配內存,malloc可以在兩個不同的進程中返回相同的地址嗎?

malloc()在兩個進程中是否有任何機會返回相同的起始地址? 如果不是,那麼誰來照顧這個。 如果是,那麼這兩個進程都可以在此地址訪問相同的數據。

+0

我們正在使用虛擬地址! – phoxis

回答

11

是否有任何機會,兩個過程的malloc()返回相同的起始地址。

是的,但是這是沒有問題的。

你不明白那是什麼操作系統,首先處理你的物理空間,讓您 - 程序等只看到虛擬地址。只有一個虛擬地址空間,但是,操作系統(現在讓我們堅持32位)將它分開。在Windows上,上半部分(0xA0000000 +)屬於內核,下半部分屬於用戶模式進程。這被稱爲2GB/2GB分割。在Linux中,除法是3GB/1GB - 見this article

內核存儲器被限定在PAGE_OFFSET,其在86是0xC0000000的,或3千兆字節開始。 (這是定義3gig/1gig分割的地方。)PAGE_OFFSET之上的每個虛擬地址都是內核,PAGE_OFFSET下面的任何地址都是用戶地址。

現在,當一個進程開關(相對於上下文切換)時,所有屬於當前處理的頁的是從虛擬存儲器映射的(不一定尋呼它們)和所有頁面的屬於(免責聲明:這可能不完全正確;理論上可以將頁面標記爲髒等等,而不是在訪問上覆制)。

分裂的原因是,出於性能原因,虛擬內存空間的上半部分可以保持映射到操作系統內核。

所以,雖然malloc的可能在給定的兩個過程返回相同的值,這並不關係,因爲:

  1. 身體,他們不是同一個地址。
  2. 進程不會在任何地方共享虛擬內存。

對於64位系統,由於我們當前只使用這些位中的48位,所以在用戶模式的底部和內核模式之間存在一個不可尋址的鴻溝(尚未)。

+0

實際上它是一個3GB/1GB的分割,0xc0000000是32位地址空間的最後一個千兆字節的開始地址。 – Benoit

+0

@Benoit在這種情況下,我塞滿了我的號碼。除非您明確要求它是[/LARGEADDRESSAWARE'](http://msdn.microsoft.com/en-us/library/wz223b1z(v=vs.80).aspx),否則通常在Windows上會有2GB/2GB的分割) – 2012-07-04 12:42:08

+1

我不知道Windows,ty的信息。我指出,因爲你提到它的時候,Linux的內核空間從0xc0000000開始。 – Benoit

2

是的,可以malloc()在單獨的進程返回相同的指針值,如果在單獨的地址空間,其經由虛擬存儲器實現運行的進程。但是,在這種情況下,它們將不會訪問相同的物理內存位置,顯然,地址處的數據不必相同。

1

進程是線程和地址空間的集合。該地址空間被稱爲虛擬,因爲它的每個字節不一定由物理內存支持。如果過程中的應用程序通過有效使用此內存而最終結束,則虛擬地址空間的段最終將由物理內存支持。

所以,malloc()可以針對兩個處理返回相同的地址,但它是沒有問題的,因爲這些malloced記憶將通過物理存儲器不同的段進行備份。

此外malloc()實現是不可重入的,因此在共享相同地址空間的不同線程中調用malloc()希望不會導致返回相同的虛擬地址。

+0

「希望」?你的意思是「大多是可重入/線程安全的」? –

+0

調用'malloc()'的兩個線程不能同時修改bookeeping結構。有些機制應該使'malloc()'有一種線程安全,是的。 – Benoit

+0

true,或者在malloc()/ free()內部或外部。 –

相關問題