HANDLE WINAPI HeapCreate(
__in DWORD flOptions,
__in SIZE_T dwInitialSize,
__in SIZE_T dwMaximumSize );
第一個參數f d w O p t i o n s用於修改如何在堆疊上執行各種操作。你可以設定0、H E A P N O S E R I A L I Z E、H E A P G E N E R AT E E X C E P T I O N S或者是這兩個標誌的組合。
按照默認設定,堆疊將順序訪問它自己,這樣,多個執行緒就能夠分配和釋放堆疊中的記憶體
塊而不至於破壞堆疊。當試圖從堆疊分配一個記憶體塊時, H e a p A l l o c函式(下面將要介紹)必
須執行下列操作:
1) 遍歷分配的和釋放的記憶體塊的連結表。
2) 尋找一個空閒記憶體塊的地址。
3) 通過將空閒記憶體塊標記為“已分配”分配新記憶體塊。
4) 將新記憶體塊添加給記憶體塊連結表。
下面這個例子說明為什麼應該避免使用H E A P N O S E R I A L I Z E標誌。假定有兩個執行緒試
圖同時從同一個堆疊中分配記憶體塊。執行緒1執行上面的第一步和第二步,獲得了空閒記憶體塊的
地址。但是,在該執行緒可以執行第三步之前,它的運行被執行緒2搶占,執行緒2得到一個機會來
執行上面的第一步和第二步。由於執行緒1尚未執行第三步,因此執行緒2發現了同一個空閒記憶體塊
的地址。
由於這兩個執行緒都發現了堆疊中它們認為是空閒的記憶體塊,因此執行緒1更新了連結表,給
新記憶體塊做上了“已分配”的標記。然後執行緒2也更新了連結表,給同一個記憶體塊做上了“已
分配”標記。到現在為止,兩個執行緒都沒有發現問題,但是兩個執行緒得到的是完全相同的記憶體
塊的地址。
這種類型的錯誤是很難跟蹤的,因為它不會立即表現出來。相反,這個錯誤會在後台等待
著,直到很不適合的時候才顯示出來。可能出現的問題是:
・ 記憶體塊的連結表已經被破壞。在試圖分配或釋放記憶體塊之前,這個問題不會被發現。
・ 兩個執行緒共享同一個記憶體塊。執行緒1和執行緒2會將信息寫入同一個記憶體塊。當執行緒1查看該
記憶體塊的內容時,它將無法識別執行緒2提供的數據。
・ 一個執行緒可能繼續使用該記憶體塊並且將它釋放,導致另一個執行緒改寫未分配的記憶體。這
將破壞該堆疊。
解決這個問題的辦法是讓單個執行緒獨占對堆疊和它的連結表的訪問權,直到該執行緒執行了
對堆疊的全部必要的操作。如果不使用H E A P _ N O _ S E R I A L I Z E標誌,就能夠達到這個目的。
只有當你的進程具備下面的一個或多個條件時,才能安全地使用H E A P N O S E R I A L I Z E標誌:
・ 你的進程只使用一個執行緒。
・ 你的進程使用多個執行緒,但是只有單個執行緒訪問該堆疊。
・ 你的進程使用多個執行緒,但是它設法使用其他形式的互斥機制,如關鍵代碼段、互斥對
象和信標(第8、9章中介紹),以便設法自己訪問堆疊。
如果對是否可以使用H E A P N O S E R I A L I Z E標誌沒有把握,那么請不要使用它。如果不
使用該標誌,每當調用堆疊函式時,執行緒的運行速度會受到一定的影響,但是不會破壞你的堆
棧及其數據。
454計計第三部分記憶體管理
下載
另一個標誌H E A P G E N E R AT E E X C E P T I O N S,會在分配或重新分配堆疊中的記憶體塊的嘗
試失敗時,導致系統引發一個異常條件。所謂異常條件,只不過是系統使用的另一種方法,以
便將已經出現錯誤的情況通知你的應用程式。有時在設計應用程式時讓它查看異常條件比查看
返回值要更加容易些。異常條件將在第2 3、2 4和2 5章中介紹。
H e a p C r e a t e的第二個參數d w I n i t i a l S i z e用於指明最初提交給堆疊的位元組數。如果必要的話,
H e a p C r e a t e函式會將這個值圓整為C P U頁面大小的倍數。最後一個參數d w M a x i m u m S i z e用於指
明堆疊能夠擴展到的最大值(即系統能夠為堆疊保留的地址空間的最大數量)。如果
d w M a x i m u m S i z e大於0,那么你創建的堆疊將具有最大值。如果嘗試分配的記憶體塊會導致堆疊
超過其最大值,那么這種嘗試就會失敗。
如果d w M a x i m u m S i z e的值是0,那么可以創建一個能夠擴展的堆疊,它沒有內在的限制。
從堆疊中分配記憶體塊只需要使堆疊不斷擴展,直到物理存儲器用完為止。如果堆疊創建成功,
H e a p C r e a t e函式返回一個句柄以標識新堆疊。該句柄可以被其他堆疊函式使用。
若要從堆疊中分配記憶體塊,只需要調用H e a p A l l o c函式