2013-08-23 47 views
3

mprotect()用於保護內存頁面,例如,使頁面爲只讀。它爲整個過程設置了這種保護,也就是說,如果頁面是隻讀的,則沒有線程可以寫入該頁面。有沒有辦法以不同的方式爲不同的線程保護頁面?例如,1個線程可以寫入頁面P,並且我的程序中的所有其他線程只能從P.是否有基於線程的mprotect?

+0

操作系統內存安全性處於進程級別。 –

+0

'mprotect'不能做到這一點。線程必須*鎖定*他們想要保留的內容。在線程中保護整個頁面的動機是什麼?你不能用鎖嗎(例如,當一個線程擁有寫鎖,而其他人都可以讀取)? –

+1

即使遇到應用程序錯誤,我也想保護這些區域,這就是爲什麼鎖定不充分的原因。是的,我知道'mprotect'不是正確的方法,所以我想知道是否有任何方法可以實現這一點。 – danyhow

回答

1

中讀取如果在「克隆」系統調用中使用CLONE_VM標誌創建線程(這是您通常的做法調用線程),那麼MMU設置與父線程相同。

這意味着兩個線程都可以進行寫訪問。

如果您不使用CLONE_VM標誌,那麼這兩個線程根本沒有共享內存!

(pthread_create()在內部設置CLONE_VM標誌)。

這將有可能做你想要的東西 - 但是這將是非常困難的:

使用共享內存功能分配所有的內存塊(例如shmget的()),而不是標準的函數(例如malloc()函數)。

如果創建了新線程,則未使用CLONE_VM標誌來直接使用「clone()」而不是「pthread_create()」。

共享內存由線程共享,由「正常」內存分配函數(例如malloc())創建的線程不在線程之間共享。 mmap()映射的內存也是如此。

當創建一個新線程時,會複製這些內存塊(由malloc或mmap創建),以便兩個線程在同一地址都有自己的該內存塊副本。如果一個線程寫入該地址,則另一個線程將不會看到該更改。

分配更多的「共享」內存相當棘手。如果僅在分配線程和未創建的子線程之間共享內存,則很容易。很難在已經運行的線程之間或不同的已運行線程的(間接)子線程之間共享內存。

線程沒有共享堆棧內存,因此它們不能訪問彼此的堆棧。

全局變量和「靜態」變量不是默認共享的 - 爲了讓它們在線程之間「共享」,需要一些棘手的編程。

+0

這是一個有趣的想法。又怎麼能讓線程對共享數據擁有不同的權限呢?每個線程可以使用不同的'PROT_'標誌在共享內存上調用'mprotect()'嗎? – danyhow

+0

這實際上不太可能。 CLONE_SIGHAND需要CLONE_VM,CLONE_THREAD需要CLONE_SIGHAND(http://linux.die.net/man/2/clone)。因此,爲了不共享內存映射,新線程必須是它自己的進程。如果你願意爲線程使用進程,那麼這將工作得很好,但你不需要使用clone()。 – zmccord

+0

是的 - 然後線程將是單獨的進程。但是使用fork()系統調用將不起作用(因爲內存不會被共享),所以clone()將是唯一能夠創建「線程」進程的系統調用。 –

相關問題