說庫x.so
具有一個全局變量y
,它由庫中的函數(如fun1
)操縱。.so庫中的全局變量
當一個進程p1
被加載到RAM,其代碼是使用功能fun1
從文庫x.so
,x.so將由ld.so和功能符號被加載到RAM(如果尚未存在)庫獲取之前解決程序開始執行。
現在在哪裏創建了這個全局變量。它在處理p1
?
當另一個進程p2
也使用fun1
(它正在對y
進行操作)時會發生什麼?
說庫x.so
具有一個全局變量y
,它由庫中的函數(如fun1
)操縱。.so庫中的全局變量
當一個進程p1
被加載到RAM,其代碼是使用功能fun1
從文庫x.so
,x.so將由ld.so和功能符號被加載到RAM(如果尚未存在)庫獲取之前解決程序開始執行。
現在在哪裏創建了這個全局變量。它在處理p1
?
當另一個進程p2
也使用fun1
(它正在對y
進行操作)時會發生什麼?
流程將獲得他們的私人副本y
,當您撥打exec
時,它將被新副本替換。它將駐留在圖書館的數據部分。
當在啓動時加載庫之前,每個進程創建自己的變量y
的實例,然後到達main
入口點。
因此,當ld.so發現當前程序正在使用庫中的函數時,它會將庫數據段中的變量的新副本創建到當前進程自己的數據段中?如果有exec()調用,則整個ld.so符號以新代碼開始解析? – tez
庫的數據段在加載庫時立即創建。它以與可執行文件全局相似的方式創建(作爲專用拷貝寫入文件支持的VM映射)。與函數符號不同 - 符號到數據的解析是直接的。當調用exec時,您的整個進程虛擬機將被替換爲新的虛擬機,並且所有庫都將從頭開始重新映射。 –
@SergeyL,如果您執行'exec()'風格調用,則概念上整個進程的內存區域將被複制,以便孩子獲得全新副本。在實踐中,爲了提高效率,操作系統只允許他們訪問共享只讀副本,並且僅在寫入時進行復制(寫時複製)。不涉及重新映射。 – vonbrand