《windows核心程式設計》 執行緒棧

2021-09-20 14:45:28 字數 1448 閱讀 8951

當系統建立執行緒的時候,會為執行緒棧預訂一塊位址空間區域,並給該區域調撥一些物理儲存器。缺省會預訂1mb的位址空間並調撥兩個頁面的儲存器。但是在構建 應用程式的時候可以改變這個預設值

在構建應用程式的時候鏈結器會把棧的大小寫入到exe和dll檔案的pe檔案頭中,當建立執行緒的時候會根據pe檔案頭中的大小來預訂空間區域。在呼叫createthread或_beginthreadex的時候開發人員可以指定需要在一開始就調撥的位址空間大小和儲存器大小。

下面顯示了一台頁面大小為4kb的機器上線程棧的位址空間區域(基址為0x08100000 )。該執行緒棧的位址空間區域和所調撥給該區域的都具有page_readwrite保護屬性。

假設執行緒呼叫樹非常深,cpu的棧指標暫存器指向的記憶體位址為0x08003004現在當執行緒呼叫另乙個函式時,系統必須調撥更多的物理儲存器。但是當系統給0x0800100的頁面調撥物理儲存器時,它的做法和給區域中的其他部分調撥物理儲存器有所不同。

由上圖可知,系統會除去0x08001000處的page_guard保護屬性標誌,然後給位址為0x08001000的頁面調撥物理存器。區別在於系統不會給剛調撥的物理儲存器0x09001000指定防護屬性。意味著棧的位址空間已經放滿了字所能容納得下的所有物理儲存器。系統永遠不會給區域底部的那個頁面調撥儲存器。

當系統給0x080000000呼叫物理儲存器時,它會執行乙個額外的操作:丟擲exception_stack_overflow異常。

可以用函式setthreadstackguarante函式來設定丟擲前面講的exception_stack_overflow異常。

為什麼系統始終不給棧位址空間最底部的頁面調撥物理儲存器。這樣做目的是為了保護程序中其它資料。使他們不會因為意外的記憶體寫越界而遭到破壞。如果棧越過了所預訂的區域,那麼執行緒就會覆蓋程序位址空間中其它資料。

另一種很難找到的缺陷是 棧下溢 看下面**

int winapi winmain(hinstance hinstexe,hinstance ,ptstr pszcmdline,int

ncmdshow)

dword winapi threadfunc(pvoid pvparam)

16.1 c/c++執行庫的棧檢查函式

c++執行庫中有乙個棧檢查函式。在編譯**時,編譯器會在必要時生成**來呼叫該函式。這個函式的目的是為了確保已經給執行緒棧調撥了物理儲存器。

出處:

張東公升

windows核心程式設計 執行緒的TLS

tls thread local storage 執行緒本地儲存 本質 對於一些全域性變數,為每乙個執行緒分配乙個例項,各執行緒只使用自己的例項,而不用去爭搶那乙個全域性變數的例項 tls的真實一億在於不用為每個執行緒去定義乙個全域性匾蛉,而使用特殊關鍵字或者api自動為每個執行緒例項分配私有的全域...

Windows核心程式設計

內容簡介 這是一本經典的windows核心程式設計指南,從第1版到第5版,引領著數十萬程式設計師走入windows開發陣營,培養了大批精英。作為windows開發人員的必備參考,本書是為打算理解windows的c和c 程式設計師精心設計的。第5版全面覆蓋windows xp,windows vist...

WINDOWS核心程式設計 核心物件

今天想把看的第三章的心得寫下來。這章主要介紹了核心物件。在windows中,核心物件是由作業系統來管理,儘管使用者能夠建立它,但是在建立之後,使用者對該核心物件的操作都是委託給作業系統。通常使用者建立和使用的物件分為 使用者物件 如 hicon createicon prama gdi物件函式以及核...