核心物件與控制代碼的關係

2021-06-19 15:10:48 字數 1664 閱讀 2136

一:乙個物件是不是核心物件,通常可以看建立此物件api的引數中是否需要:psecurity_attributes 型別的引數。

三:每個程序中有乙個控制代碼表(handle table),這個控制代碼表僅供核心物件使用,如下圖:

四:解開此中的秘密

比如呼叫建立乙個執行緒的api:

handle  hthread ;

dword threadid;

hthread = createthread(... , &threadid);

此時發生的事情是:系統查詢控制代碼表,找到一項可用的分配給以上建立的執行緒;,hthread >> 2 得到控制代碼在控制代碼表中的索引(windows作業系統內部使用hthread最後兩位,所以

右移兩位得到真正的索引);也是此時核心物件被建立,其資料結構中的引用計數初始為1(這樣理解:只要核心物件被建立,其引用計數被初始化為1),這裡實則發生兩件事:建立了乙個核心物件和建立執行緒的函式開啟了此物件,所以核心物件的引用計數加1,這時引用計數就為2了。

當呼叫closehandle(hthread); 時發生這樣的事情:系統通過hthread計算出此控制代碼在控制代碼表中的索引,然後把那一項處理後標註為空閒可用的項,核心物件的引用計數減1即此時此核心物件的引用計數為1,之後這個執行緒控制代碼與建立時產生的核心物件已經沒有任何關係了。

問題:我們知道只有當核心物件的引用計數為0時,核心物件才會被銷毀,而此時它的引用計數為1,那它什麼時候會被銷毀?

答:當此執行緒結束的時候,它的引用計數再減1即為0,核心物件被銷毀。此時又有乙個新問題產生:我們已經關閉了執行緒控制代碼,也就是這個執行緒控制代碼已經和核心物件沒有瓜葛了,那麼那個核心物件是怎麼又可以和此執行緒聯絡起來了呢? 我覺得是建立執行緒時產生的那個執行緒id,接下來我就證明那個id與核心物件是有聯絡的:

請看如下簡單的程式:

#include #include #include dword winapi threadproc( lpvoid lpparameter)

return 0;

}int main()

圖1:

圖2:

除錯此程式觀察headle2的值,可以發現headle2的值是有效的,即函式呼叫是成功的,證明了執行緒id與執行緒建立當初產生的核心物件是有關係的。

可以猜想:當執行緒結束時,系統通過執行緒id與核心物件聯絡,使其引用計數減1,為0核心物件被銷毀。

ps:觀察以上兩圖,當把closehandle(hthread)這一句注釋掉,以上程式三次呼叫openthread(),返回值是不相同的,說明返回的控制代碼不是原來控制代碼表中原來

的索引項,而是新建了乙個內容一樣的索引項。讓closehandle(hthread); 這句也執行,再看看結果:hthread與headle2 的值是一樣,證明了系統

管理控制代碼表的規則:我們把hthread關閉之後,它所在的索引項就被標記為可用;當需要向控制代碼表中加入新項時會查詢第一項可用的索引項,這就是

hthread與headle2 的值是一樣的原因。

深入解析MFC 控制代碼與物件的關係

在windows體系中,很多物件都是以控制代碼的形式展示給開發人員的。比如視窗控制代碼 hwnd 繪圖裝置 hdc 等等。然後大部分的api函式則圍繞這些控制代碼做文章。比如showwindow,setwindowtext,textout等等。這些api函式的第乙個引數通常就是控制代碼了。但是在c ...

程序的核心物件控制代碼表

當程序初始化的時候,系統會為其分配乙個控制代碼表。該控制代碼表只用於核心物件。具體該控制代碼表在系統中是種怎樣的結構和是怎麼被系統管理的,現在沒有說明文件。程序控制代碼表的大體結構如下 index pointer to kernal object memory block access mask f...

程序的核心物件控制代碼表

當乙個程序被初始化時,系統要為它分配乙個控制代碼表。該控制代碼表只用於核心物件,不用於使用者物件或gdi物件。它只是個資料結構的陣列。每個結構都包含乙個指向核心物件的指標 乙個訪問遮蔽和一些標誌。程序的控制代碼結構 索引 核心物件記憶體塊的指標 訪問遮蔽 標誌位的dword 標誌 標誌位的dword...