多線程訪問堆對象
大家好!今天我給大家介紹一下在多線程中訪問堆對象的方法。在這次的測試代碼中,我會創(chuàng)建兩個子線程,其中一個會不斷的將堆上的內(nèi)存重新分配為2048個字節(jié),而另一個則會將堆上的內(nèi)存重新分配為8個字節(jié)。在主線
大家好!今天我給大家介紹一下在多線程中訪問堆對象的方法。在這次的測試代碼中,我會創(chuàng)建兩個子線程,其中一個會不斷的將堆上的內(nèi)存重新分配為2048個字節(jié),而另一個則會將堆上的內(nèi)存重新分配為8個字節(jié)。在主線程的main函數(shù)中,循環(huán)獲取當(dāng)前已分配內(nèi)存的大小并輸出獲取到的值。為了讓程序能夠正常結(jié)束,main函數(shù)中僅獲取60次即自動結(jié)束程序。如果您覺得這篇教程有幫助,請為我投上寶貴的一票(順便求個關(guān)注),謝謝!
創(chuàng)建項(xiàng)目和定義線程回調(diào)函數(shù)
首先,打開VS2017,新建一個名為“MemoryMgtDemo5”的“Windows控制臺應(yīng)用程序”項(xiàng)目。然后在main函數(shù)之上,定義兩個線程回調(diào)函數(shù)onFirstThread和onSecondThread。在這兩個函數(shù)中添加線程函數(shù)的while循環(huán)框架代碼。循環(huán)中需要的結(jié)束標(biāo)記變量可以定義為全局變量,這樣在main函數(shù)中,可以通過控制該變量的值結(jié)束線程循環(huán),令其正常退出。同時,為了在所有線程中都能訪問進(jìn)程默認(rèn)堆和該堆上分配的內(nèi)存,需要將這兩個變量也定義為全局變量。
獲取進(jìn)程默認(rèn)堆和分配內(nèi)存
在main函數(shù)中,先獲取進(jìn)程的默認(rèn)堆,然后在其上分配512字節(jié)的內(nèi)存空間。接下來,創(chuàng)建兩個線程,并通過一個循環(huán)獲取當(dāng)前已分配內(nèi)存的大小。完成循環(huán)代碼后,將線程退出標(biāo)記置為TRUE,并調(diào)用Windows API函數(shù)WaitForMultipleObjects等待兩個子線程正常退出。
重新分配堆內(nèi)存
代碼編寫完畢后,調(diào)試運(yùn)行程序,確認(rèn)程序可以正常工作。由于此時子線程中什么也沒做,因此程序會持續(xù)打印512字節(jié)的內(nèi)存大小。然后關(guān)閉控制臺窗口,返回到onFirstThread函數(shù)中,在該函數(shù)中,以同步方式重新分配_gsMem內(nèi)存空間為2048個字節(jié)。接著,在onSecondThread函數(shù)中添加使用HeapLock和HeapUnlock互斥訪問默認(rèn)堆以及重新分配內(nèi)存大小為8字節(jié)的代碼。對于默認(rèn)堆而言,默認(rèn)就是互斥訪問的,因此在調(diào)用HeapReAlloc函數(shù)時可以無需指定HEAP_NO_SERIALIZE標(biāo)記以及使用HeapLock來鎖定默認(rèn)堆。
測試多線程訪問堆對象
填寫完代碼后,再次調(diào)試運(yùn)行程序。在彈出的控制臺窗口中,可以看到交替打印的2048字節(jié)和8字節(jié)內(nèi)存大小,表示兩個線程均在正常工作。
總結(jié)
Windows API中堆函數(shù)部分的基本用法已經(jīng)介紹完畢,不過其中還有很多細(xì)節(jié)需要仔細(xì)閱讀并編寫實(shí)踐代碼才能更好地理解。希望你以此為基礎(chǔ)繼續(xù)努力學(xué)習(xí),Enjoy!