核心物件&控制程式碼

shell_nut發表於2019-05-10

  專案工程程式碼中設計控制程式碼的使用,一時不知控制程式碼是何物,通過查閱自學之後,對控制程式碼及其使用有一個初步的瞭解。分享出來,算是拋磚引玉吧。
  在闡述控制程式碼之前,先說明一下核心物件。

1 核心物件的概念

  核心物件就是一個記憶體塊,有核心分配,只能由核心訪問。

核心物件&控制程式碼

  記憶體塊是一種資料結構,其中的資料成員負責維護該物件的相應資訊,這個資料結構以及其中的資料成員只能由核心訪問,應用程式是無法訪問到的,更別說修改其中的資料成員了。

  如何訪問這些核心物件(記憶體塊)呢?

  作業系統為使用者封裝了一組API,使用者可以通過這些API訪問核心物件(記憶體塊)。比如,建立核心物件(記憶體塊)時,使用者呼叫API中的建立核心物件函式,由核心建立一個核心物件(分配一塊記憶體)。

  核心物件建立好之後,用一個控制程式碼來標識該核心物件(記憶體塊),這個控制程式碼作為函式值返回。這個控制程式碼就是個整數,32位機控制程式碼就是32bit,64位機控制程式碼就是64bit,同一程式中的任何執行緒都能使用這個控制程式碼,當需要操作核心物件(記憶體塊)時,通過API將這個控制程式碼傳給核心,核心就知道是對哪個核心物件(記憶體塊)進行操作了。

建立核心物件,引出控制程式碼。 

2 核心物件的使用計數

  在應用程式中,可能有多個程式,這些程式中的一個或多個可能會訪問同一個核心物件。核心物件有使用就會有撤銷,那麼什麼情況下核心會撤銷某個核心物件呢。核心的使用計數就派上用場了。使用計數是核心物件這個資料結構的資料成員,通過使用計數就能知道該核心物件被多少個程式使用。開始建立核心物件時,使用計數置為1,之後每多一個不同的程式使用該核心物件,使用計數就自加1.

  無論什麼方式建立核心物件,我們都需要呼叫 ClosseHandle 向系統表明我們已經結束使用物件.就在 CloseHandle 函式返回前,它會清除程式控制程式碼表中對應的記錄項 -- 這個控制程式碼現在對我們的程式來說是無效的,不要在試圖利用它.換句話說,一旦呼叫 CloseHandle, 我們的程式就不能訪問那個核心物件.

  當程式關閉時,核心自動訪問該程式仍然開啟的核心物件的使用計數,該程式關聯的每個核心物件的使用計數自減1,當使用計數減到0時,核心就會撤銷該核心物件。

  核心物件的使用計數有些像智慧指標。

3 控制程式碼

  核心物件建立好之後,用一個控制程式碼來標識該核心物件(記憶體塊),這個控制程式碼作為函式值返回。這個控制程式碼就是個整數,32位機控制程式碼就是32bit,64位機控制程式碼就是64bit。

  在同一程式中,一個控制程式碼對應一個核心物件,我們在訪問核心物件(記憶體塊)時,就是通過控制程式碼告訴核心,我要訪問哪個核心物件。

  通俗的說,控制程式碼,就是個編號,作業系統對於我們來說就是個黑箱,我們通過控制程式碼向作業系統要東西。

4 控制程式碼表

  當一個程式被初始化時,系統要為它分配一個控制程式碼表.該控制程式碼表只用於核心物件,不用於使用者物件或GDI物件.控制程式碼表也是由核心操作。程式表包含的元素如下所示:

索引  核心物件  記憶體塊的指標訪問遮蔽(標誌位的DWORD)  標誌(標誌位的DWORD)

  程式被初次初始化時,控制程式碼表是空的。

  當程式中的執行緒建立核心物件時,核心給該物件分配一塊記憶體,並對其初始化。核心遍歷該程式的控制程式碼表,找出一個空閒位置,設定核心物件,記憶體塊指標,訪問掩碼,標識,並獲取該位置的索引,作為函式值返回,這個索引就是我們所說的控制程式碼。這個控制程式碼只能有同一個程式的所有執行緒使用, 系統用索引來表示核心物件的資訊儲存在程式控制程式碼表中的具體位置。其他程式不能使用該程式的索引,因為控制程式碼表不同(每個程式有一個單獨的控制程式碼表)。

  所以,控制程式碼實際上是控制程式碼表的索引。可以這麼理解,指標指向一塊記憶體空間,那麼控制程式碼就是指向其對應的核心物件,通過作業系統提供的API吧控制程式碼傳給核心,核心就知道要操作那個核心物件。

相關文章