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