使用C++Builder注意事項(xiàng)
C++Builder作為一個(gè)高效的C++程序語(yǔ)言,其混合了函數(shù)語(yǔ)言和物件導(dǎo)向程序編制語(yǔ)言,并且完美的適用于編程、算法、技術(shù)和探索性開(kāi)發(fā),因此可以在使用的過(guò)程當(dāng)中感受到趣味性和吸引力。
注意,線程對(duì)象不允許控制線程堆棧的大小或其安全屬性。若需要控制這些,必須使用WindowsAPI的Create Thread()或Begin Thread()函數(shù)。TThread類(lèi)有以下一些屬性和方法:
1) 屬性:
◆Priority:優(yōu)先級(jí)屬性。可以設(shè)置線程的優(yōu)先級(jí)。
◆Return Value:返回值屬性。當(dāng)線程介紹時(shí)返回給其他線程一個(gè)數(shù)值。
◆Suspended:掛起屬性。可以判斷線程是否被掛起。
◆Terminated:結(jié)束屬性。用來(lái)標(biāo)志是否應(yīng)該結(jié)束線程。
◆ThreadID:標(biāo)識(shí)號(hào)屬性。在整個(gè)系統(tǒng)中線程的標(biāo)識(shí)號(hào)。使用Windows API函數(shù)時(shí)該屬性非常有用。
2)方法:
◆Do Terminate:產(chǎn)生一個(gè)On Terminate事件,但是不結(jié)束線程的執(zhí)行。
◆Resume:?jiǎn)拘岩粋€(gè)線程繼續(xù)執(zhí)行。
◆Suspend:掛起一個(gè)線程,要與Resume過(guò)程成對(duì)使用。
◆Synchronize:由主C++線程調(diào)用的一個(gè)同步過(guò)程。
◆Terminate:將Terminate屬性設(shè)置為T(mén)rue,中止線程的執(zhí)行。
◆Wait For:等待線程的中止并返回Return Value屬性的數(shù)值。
2、協(xié)調(diào)線程
在編寫(xiě)線程執(zhí)行時(shí)運(yùn)行的代碼時(shí),必須考慮到可能同步執(zhí)行的其他線程的行為。特別注意,避免兩個(gè)線程試圖同時(shí)使用相同的全局對(duì)象或變量。另外,一個(gè)線程中的代碼會(huì)依賴(lài)其他線程執(zhí)行任務(wù)的結(jié)果。
1) 避免同時(shí)訪問(wèn)
為避免在訪問(wèn)全局對(duì)象或變量時(shí)與其他線程發(fā)生沖突,可能需要暫停其他線程的執(zhí)行,直到該線程代碼完成操作。
(1)鎖定對(duì)象。一些對(duì)象內(nèi)置了鎖定功能,以防止其他線程使用該對(duì)象的實(shí)例。例如,畫(huà)布對(duì)象(TCanvas及其派生類(lèi))有一種Lock()函數(shù)可以防止其他線程訪問(wèn)畫(huà)布,直到調(diào)用Unlock()函數(shù)。顯然,這種方法只對(duì)部分類(lèi)有效。
(2)使用重要區(qū)段。若對(duì)象沒(méi)有提供內(nèi)置的鎖定功能,可使用重要區(qū)段。重要區(qū)段像門(mén)一樣,每次只允許一個(gè)線程進(jìn)入,要使用重要區(qū)段,需創(chuàng)建TCriticalSection的全局實(shí)例。TCriticalSection有兩個(gè)函數(shù):Acquire()(阻止其他線程執(zhí)行該區(qū)域)及Release()(取消對(duì)其他線程的阻止)。
(3)使用多重讀、獨(dú)占寫(xiě)的同步器。當(dāng)使用重要區(qū)段來(lái)保護(hù)全局內(nèi)存時(shí),每次只有一個(gè)線程可以使用該內(nèi)存。這種保護(hù)可能會(huì)超出了需要,特別是有一個(gè)經(jīng)常讀但很少寫(xiě)的對(duì)象或變量時(shí)更是如此。多個(gè)線程同時(shí)讀相同內(nèi)存但沒(méi)有線程寫(xiě)內(nèi)存是沒(méi)有危險(xiǎn)的。
當(dāng)有一些經(jīng)常被讀,但是很少寫(xiě)的全局變量時(shí),可用TMultiReadExclusiveWriteSynchronizer對(duì)象保護(hù)它。這個(gè)對(duì)象和重要區(qū)段一樣,但它允許多個(gè)線程同時(shí)讀,只要沒(méi)有線程寫(xiě)即可。每個(gè)需要讀內(nèi)存的線程首先要調(diào)用Begin Read()函數(shù)(確保當(dāng)前無(wú)其他線程寫(xiě)內(nèi)存),線程完成對(duì)保護(hù)內(nèi)存讀操作后,要調(diào)用End Read()函數(shù)。任何線程需要寫(xiě)保護(hù)內(nèi)存必須調(diào)用Begin Write()函數(shù)(確保當(dāng)前無(wú)其他線程讀或?qū)憙?nèi)存),完成對(duì)保護(hù)內(nèi)存寫(xiě)操作后,調(diào)用End Write()函數(shù)。
(4)使用Synchronize函數(shù):Void __fast call Synchronize (TThreadMethod &Method);
其中參數(shù)Method為一個(gè)不帶參數(shù)的過(guò)程名。在這個(gè)不帶參數(shù)的過(guò)程中是一些訪問(wèn)VCL的代碼。我們可以在Execute過(guò)程中調(diào)用Synchronize過(guò)程來(lái)避免對(duì)VCL的并發(fā)訪問(wèn)。程序運(yùn)行期間的具體過(guò)程實(shí)際上是由Synchronize過(guò)程來(lái)通知主線程。
然后主線程在適當(dāng)?shù)臅r(shí)機(jī)來(lái)執(zhí)行Synchronize過(guò)程的參數(shù)列表中的那個(gè)不帶參數(shù)的過(guò)程。在多個(gè)線程的情況下,主線程將Synchronize過(guò)程發(fā)過(guò)來(lái)的通知放到消息隊(duì)列中,然后逐個(gè)地響應(yīng)這些消息。通過(guò)這種機(jī)制Synchronize實(shí)現(xiàn)了線程之間地同步。
2) 等待其他線程
使用C++Builder若線程必須等待另一線程完成某項(xiàng)任務(wù),可讓線程臨時(shí)中斷執(zhí)行。然后,要么等待另一線程完全執(zhí)行結(jié)束,要么等待另一線程通知完成了該任務(wù)。
(1)等待線程執(zhí)行結(jié)束
要等待另一線程執(zhí)行結(jié)束,使用它地Wait For()函數(shù)。Wait For函數(shù)直到那個(gè)線程終止才返回,終止的方式要么完成了其Execute()函數(shù),要么由于一個(gè)異常。
(2)等待任務(wù)完成。有時(shí),只需要等待線程完成一些操作而不是等待線程執(zhí)行結(jié)束。為此,可使用一個(gè)事件對(duì)象。事件對(duì)象(TEvent)應(yīng)具有全局范圍以便他們能夠?yàn)樗芯€程可見(jiàn)。
當(dāng)一個(gè)線程完成一個(gè)被其他線程依賴(lài)的操作時(shí),調(diào)用TEvent::Set Event()函數(shù)。Set Event發(fā)出一個(gè)信號(hào),以便其他線程可以檢查并得知操作完成。要關(guān)掉信號(hào),則使用Reset Event()函數(shù)。
例如,當(dāng)必須等待若干線程完成其執(zhí)行而不是單個(gè)線程時(shí)。因?yàn)椴恢滥膫€(gè)線程最后完成,使用C++Builder函數(shù)時(shí),此時(shí),可通過(guò)調(diào)用Set Event以在線程結(jié)束時(shí)累加計(jì)數(shù)值并在最后一個(gè)線程結(jié)束時(shí)發(fā)出信號(hào)以指示所有線程結(jié)束。
【編輯推薦】

















