1. 什么是內核對象
內核對象是操作系統為一些系統級的對象(像進程,線程,信號量)維護的一些數據結構。這些數據構保存了與系統級對象相關的系統級信息。
例如:所有內核對象都會保存該對象的引用計數。進程對象會保存進程ID。文件對象會保存當前字節偏移量,共享模式,打開模式等。
操作系統中所有內核對象對是保存在一塊內存空間中,系統上所有的進程都共享這一塊內存空間。
2.內核對象的訪問方式
這些內核對象不能被應用程序直接訪問,應用程序只能通過操作系統提供的API對他們進行操作。而對操作系統API的訪問過程中,操作系統會對訪問的安全性進行保證。這樣避免應用程序對內核對象進行操作而導致系統出現錯誤。
多個進程可以共享訪問同一個內核對象。
當應用程序創建或打開一個內核對象時,系統API會返回給應用程序一個句柄(該句柄是進程級別的)。在應用程序中之后便可以使用該句柄來指定對該內核對象進行操作。
該句柄是進程級別的,因此同一個內核對象在兩個進程中的句柄不會一樣。進程如果使用內核對象在其他進程中的句柄來訪問內核對象時會出錯。
3. 內核對象的生命周期
每個內核對象都會有一個引用計數的概念,內核對象被創建的時候,該值是1。之后每一個新的進程獲得對該內核對象訪問(我理解為獲得一個代表該內核對象的句柄),則引用計數加1.當每已獲得訪問的進程釋放訪問權利后(進程關閉內核對象的句柄),引用計數會被減1. 當引用計數減少至0后,操作系統將會把該內核對象銷毀掉。(這個機制有點像COM的生命周期機制)
既然句柄是進程級的,那如果在同一進程中多個地方打開同一個內核對象。那獲得的句柄應該是同一個,引用計數應該只會加1?(有待驗證TODO)
4.內核對象的共享
通過給內存對象命名即可以實現內核對象在多個進程中共享。
具體實現方式是,在創建內核對象時提供一個名字。然后在其他進程中訪問(創建或打開)這個內核對象是仍然使用這個名字。
當用一個特定的名稱去創建一個內核對象時,如果該特定名稱的內核對象已經存在,則系統會返回一個句柄指向已經存在的這個內核對象。並將其引用計數加1.
如果實現了內核對象的共享,其實就面臨着一個問題。系統中仍何進程都可以訪問該內核對象,這樣有可能會為應用程序的正常工作帶來麻煩。