西西軟件下載最安全的下載網(wǎng)站、值得信賴的軟件下載站!
鐢熸椿鏈嶅姟
鏀粯瀹濋挶鍖�(Alipay)V10.2.53.7000 瀹夊崜鐗�鏀粯瀹濋挶鍖�(Alipay)V10.2.53.7000 瀹夊崜鐗�
鐧惧害鍦板浘瀵艰埅2022V15.12.10 瀹夊崜鎵嬫満鐗�鐧惧害鍦板浘瀵艰埅2022V15.12.10 瀹夊崜鎵嬫満鐗�
鎵嬫満娣樺疂瀹㈡埛绔痸10.8.40瀹樻柟鏈€鏂扮増鎵嬫満娣樺疂瀹㈡埛绔痸10.8.40瀹樻柟鏈€鏂扮増
鐣呴€旂綉鎵嬫満瀹㈡埛绔痸5.6.9 瀹樻柟鏈€鏂扮増鐣呴€旂綉鎵嬫満瀹㈡埛绔痸5.6.9 瀹樻柟鏈€鏂扮増
鍗冭亰鐭ヨ瘑鏈嶅姟appv4.5.1瀹樻柟鐗�鍗冭亰鐭ヨ瘑鏈嶅姟appv4.5.1瀹樻柟鐗�
褰遍煶鎾斁
p2psearcher瀹夊崜鐗�7.3  鎵嬫満鐗�p2psearcher瀹夊崜鐗�7.3 鎵嬫満鐗�
閰风嫍闊充箰2022瀹樻柟鐗圴11.0.8 瀹樻柟瀹夊崜鐗�閰风嫍闊充箰2022瀹樻柟鐗圴11.0.8 瀹樻柟瀹夊崜鐗�
鐖卞鑹烘墜鏈虹増v13.1.0鐖卞鑹烘墜鏈虹増v13.1.0
鐧惧害褰遍煶7.13.0 瀹樻柟鏈€鏂扮増鐧惧害褰遍煶7.13.0 瀹樻柟鏈€鏂扮増
褰遍煶鍏堥攱v6.9.0 瀹夊崜鎵嬫満鐗�褰遍煶鍏堥攱v6.9.0 瀹夊崜鎵嬫満鐗�
闃呰宸ュ叿
鑵捐鍔ㄦ极V9.11.5 瀹夊崜鐗�鑵捐鍔ㄦ极V9.11.5 瀹夊崜鐗�
涔︽棗灏忚鍏嶈垂鐗堟湰v11.5.5.153 瀹樻柟鏈€鏂扮増涔︽棗灏忚鍏嶈垂鐗堟湰v11.5.5.153 瀹樻柟鏈€鏂扮増
QQ闃呰鍣╝ppV7.7.1.910 瀹樻柟鏈€鏂扮増QQ闃呰鍣╝ppV7.7.1.910 瀹樻柟鏈€鏂扮増
鎳掍汉鐣呭惉鍚功appv7.1.5 瀹樻柟瀹夊崜鐗�鎳掍汉鐣呭惉鍚功appv7.1.5 瀹樻柟瀹夊崜鐗�
璧风偣璇讳功app鏂扮増鏈�20227.9.186 瀹夊崜鐗�璧风偣璇讳功app鏂扮増鏈�20227.9.186 瀹夊崜鐗�
閲戣瀺鐞嗚储
骞冲畨璇佸埜瀹塭鐞嗚储V9.1.0.1 瀹樻柟瀹夊崜鐗�骞冲畨璇佸埜瀹塭鐞嗚储V9.1.0.1 瀹樻柟瀹夊崜鐗�
娴烽€氳瘉鍒告墜鏈虹増(e娴烽€氳储)8.71 瀹樻柟瀹夊崜鐗�娴烽€氳瘉鍒告墜鏈虹増(e娴烽€氳储)8.71 瀹樻柟瀹夊崜鐗�
涓滄捣璇佸埜涓滄捣鐞嗚储4.0.5 瀹夊崜鐗�涓滄捣璇佸埜涓滄捣鐞嗚储4.0.5 瀹夊崜鐗�
涓摱璇佸埜绉诲姩鐞嗚储杞欢6.02.010 瀹樻柟瀹夊崜鐗�涓摱璇佸埜绉诲姩鐞嗚储杞欢6.02.010 瀹樻柟瀹夊崜鐗�
鍗庨緳璇佸埜灏忛噾鎵嬫満鐞嗚储杞欢3.2.4 瀹夊崜鐗�鍗庨緳璇佸埜灏忛噾鎵嬫満鐞嗚储杞欢3.2.4 瀹夊崜鐗�
鎵嬫満閾惰
绂忓缓鍐滄潙淇$敤绀炬墜鏈洪摱琛屽鎴风2.3.4 瀹夊崜鐗�绂忓缓鍐滄潙淇$敤绀炬墜鏈洪摱琛屽鎴风2.3.4 瀹夊崜鐗�
鏄撳埗浣滆棰戝壀杈慳pp4.1.16瀹夊崜鐗�鏄撳埗浣滆棰戝壀杈慳pp4.1.16瀹夊崜鐗�
鏀粯瀹濋挶鍖�(Alipay)V10.2.53.7000 瀹夊崜鐗�鏀粯瀹濋挶鍖�(Alipay)V10.2.53.7000 瀹夊崜鐗�
涓浗宸ュ晢閾惰鎵嬫満閾惰appV7.0.1.2.5 瀹夊崜鐗�涓浗宸ュ晢閾惰鎵嬫満閾惰appV7.0.1.2.5 瀹夊崜鐗�
涓浗閾惰鎵嬫満閾惰瀹㈡埛绔�7.2.5 瀹樻柟瀹夊崜鐗�涓浗閾惰鎵嬫満閾惰瀹㈡埛绔�7.2.5 瀹樻柟瀹夊崜鐗�
浼戦棽鐩婃櫤
鑵捐鐚庨奔杈句汉鎵嬫満鐗圴2.3.0.0 瀹樻柟瀹夊崜鐗�鑵捐鐚庨奔杈句汉鎵嬫満鐗圴2.3.0.0 瀹樻柟瀹夊崜鐗�
鍔茶垶鍥㈠畼鏂规鐗堟墜娓竩1.2.1瀹樻柟鐗�鍔茶垶鍥㈠畼鏂规鐗堟墜娓竩1.2.1瀹樻柟鐗�
楗ラタ椴ㄩ奔杩涘寲鏃犻檺閽荤煶鐗坴7.8.0.0瀹夊崜鐗�楗ラタ椴ㄩ奔杩涘寲鏃犻檺閽荤煶鐗坴7.8.0.0瀹夊崜鐗�
妞嶇墿澶ф垬鍍靛案鍏ㄦ槑鏄�1.0.91 瀹夊崜鐗�妞嶇墿澶ф垬鍍靛案鍏ㄦ槑鏄�1.0.91 瀹夊崜鐗�
鍔ㄤ綔灏勫嚮
鍦颁笅鍩庣獊鍑昏€卋t鐗�1.6.3 瀹樻柟鐗�鍦颁笅鍩庣獊鍑昏€卋t鐗�1.6.3 瀹樻柟鐗�
瑁呯敳鑱旂洘1.325.157 瀹夊崜鐗�瑁呯敳鑱旂洘1.325.157 瀹夊崜鐗�
鍦f枟澹槦鐭㈤泦缁搗4.2.1 瀹夊崜鐗�鍦f枟澹槦鐭㈤泦缁搗4.2.1 瀹夊崜鐗�
閬ぉ3D鎵嬫父1.0.9瀹夊崜鐗�閬ぉ3D鎵嬫父1.0.9瀹夊崜鐗�
濉旈槻娓告垙
瀹夊崜妞嶇墿澶ф垬鍍靛案2榛戞殫鏃朵唬淇敼鐗圴1.9.5 鏈€鏂扮増瀹夊崜妞嶇墿澶ф垬鍍靛案2榛戞殫鏃朵唬淇敼鐗圴1.9.5 鏈€鏂扮増
涔辨枟瑗挎父2v1.0.150瀹夊崜鐗�涔辨枟瑗挎父2v1.0.150瀹夊崜鐗�
淇濆崼钀濆崪3鏃犻檺閽荤煶鏈€鏂扮増v2.0.0.1 瀹夊崜鐗�淇濆崼钀濆崪3鏃犻檺閽荤煶鏈€鏂扮増v2.0.0.1 瀹夊崜鐗�
鍙h鑻遍泟鍗曟満鐗�1.2.0 瀹夊崜鐗�鍙h鑻遍泟鍗曟満鐗�1.2.0 瀹夊崜鐗�
灏忓皬鍐涘洟瀹夊崜鐗�2.7.4 鏃犻檺閲戝竵淇敼鐗�灏忓皬鍐涘洟瀹夊崜鐗�2.7.4 鏃犻檺閲戝竵淇敼鐗�
璧涜溅绔炴妧
鐧诲北璧涜溅2鎵嬫父1.47.1  瀹夊崜鐗�鐧诲北璧涜溅2鎵嬫父1.47.1 瀹夊崜鐗�
涓€璧锋潵椋炶溅瀹夊崜鐗坴2.9.14 鏈€鏂扮増涓€璧锋潵椋炶溅瀹夊崜鐗坴2.9.14 鏈€鏂扮増
璺戣窇鍗′竵杞︽墜鏈虹増瀹樻柟鏈€鏂扮増v1.16.2 瀹夊崜鐗�璺戣窇鍗′竵杞︽墜鏈虹増瀹樻柟鏈€鏂扮増v1.16.2 瀹夊崜鐗�
鐙傞噹椋欒溅8鏋侀€熷噷浜戜慨鏀圭増(鍏嶆暟鎹寘)v4.6.0j 閲戝竵鏃犻檺鐗�鐙傞噹椋欒溅8鏋侀€熷噷浜戜慨鏀圭増(鍏嶆暟鎹寘)v4.6.0j 閲戝竵鏃犻檺鐗�
鐧句箰鍗冪偖鎹曢奔2021鏈€鏂扮増5.78 瀹夊崜鐗�鐧句箰鍗冪偖鎹曢奔2021鏈€鏂扮増5.78 瀹夊崜鐗�
瑙掕壊鎵紨
姊﹀够鍓戣垶鑰呭彉鎬佺増1.0.1.2瀹夊崜鐗�姊﹀够鍓戣垶鑰呭彉鎬佺増1.0.1.2瀹夊崜鐗�
浠欏浼犺ro澶嶅叴瀹夊崜鐗�1.20.3鏈€鏂扮増浠欏浼犺ro澶嶅叴瀹夊崜鐗�1.20.3鏈€鏂扮増
姊﹀够璇涗粰鎵嬫父鐗�1.3.6 瀹樻柟瀹夊崜鐗�姊﹀够璇涗粰鎵嬫父鐗�1.3.6 瀹樻柟瀹夊崜鐗�
鐜嬭€呰崳鑰€V3.72.1.1 瀹夊崜鏈€鏂板畼鏂圭増鐜嬭€呰崳鑰€V3.72.1.1 瀹夊崜鏈€鏂板畼鏂圭増
璋佸灏忚溅寮烘墜鏈虹増v1.0.49 瀹夊崜鐗�璋佸灏忚溅寮烘墜鏈虹増v1.0.49 瀹夊崜鐗�
绯荤粺杞欢
mac纾佺洏鍒嗗尯宸ュ叿(Paragon Camptune X)V10.8.12瀹樻柟鏈€鏂扮増mac纾佺洏鍒嗗尯宸ュ叿(Paragon Camptune X)V10.8.12瀹樻柟鏈€鏂扮増
鑻规灉鎿嶄綔绯荤粺MACOSX 10.9.4 Mavericks瀹屽叏鍏嶈垂鐗�鑻规灉鎿嶄綔绯荤粺MACOSX 10.9.4 Mavericks瀹屽叏鍏嶈垂鐗�
Rar瑙e帇鍒╁櫒mac鐗坴1.4 瀹樻柟鍏嶈垂鐗�Rar瑙e帇鍒╁櫒mac鐗坴1.4 瀹樻柟鍏嶈垂鐗�
Mac瀹夊崜妯℃嫙鍣�(ARC Welder)v1.0 瀹樻柟鏈€鏂扮増Mac瀹夊崜妯℃嫙鍣�(ARC Welder)v1.0 瀹樻柟鏈€鏂扮増
Charles for MacV3.9.3瀹樻柟鐗�Charles for MacV3.9.3瀹樻柟鐗�
缃戠粶宸ュ叿
鎼滅嫍娴忚鍣╩ac鐗坴5.2 瀹樻柟姝e紡鐗�鎼滅嫍娴忚鍣╩ac鐗坴5.2 瀹樻柟姝e紡鐗�
閿愭嵎瀹㈡埛绔痬ac鐗圴1.33瀹樻柟鏈€鏂扮増閿愭嵎瀹㈡埛绔痬ac鐗圴1.33瀹樻柟鏈€鏂扮増
蹇墮mac鐗坴1.3.2 瀹樻柟姝e紡鐗�蹇墮mac鐗坴1.3.2 瀹樻柟姝e紡鐗�
鏋佺偣浜旂瑪Mac鐗�7.13姝e紡鐗�鏋佺偣浜旂瑪Mac鐗�7.13姝e紡鐗�
濯掍綋宸ュ叿
Apple Logic Pro xV10.3.2Apple Logic Pro xV10.3.2
Adobe Premiere Pro CC 2017 mac鐗坴11.0.0 涓枃鐗�Adobe Premiere Pro CC 2017 mac鐗坴11.0.0 涓枃鐗�
鍗冨崈闈欏惉Mac鐗圴9.1.1 瀹樻柟鏈€鏂扮増鍗冨崈闈欏惉Mac鐗圴9.1.1 瀹樻柟鏈€鏂扮増
Mac缃戠粶鐩存挱杞欢(MacTV)v0.121 瀹樻柟鏈€鏂扮増Mac缃戠粶鐩存挱杞欢(MacTV)v0.121 瀹樻柟鏈€鏂扮増
Adobe Fireworks CS6 Mac鐗圕S6瀹樻柟绠€浣撲腑鏂囩増Adobe Fireworks CS6 Mac鐗圕S6瀹樻柟绠€浣撲腑鏂囩増
鍥惧舰鍥惧儚
AutoCAD2015 mac涓枃鐗堟湰v1.0 瀹樻柟姝e紡鐗�AutoCAD2015 mac涓枃鐗堟湰v1.0 瀹樻柟姝e紡鐗�
Adobe Photoshop cs6 mac鐗坴13.0.3 瀹樻柟涓枃鐗�Adobe Photoshop cs6 mac鐗坴13.0.3 瀹樻柟涓枃鐗�
Mac鐭㈤噺缁樺浘杞欢(Sketch mac)v3.3.2 涓枃鐗�Mac鐭㈤噺缁樺浘杞欢(Sketch mac)v3.3.2 涓枃鐗�
Adobe After Effects cs6 mac鐗坴1.0涓枃鐗�Adobe After Effects cs6 mac鐗坴1.0涓枃鐗�
Adobe InDesign cs6 mac1.0 瀹樻柟涓枃鐗�Adobe InDesign cs6 mac1.0 瀹樻柟涓枃鐗�
搴旂敤杞欢
Mac鐗堝揩鎾�1.1.26 瀹樻柟姝e紡鐗圼dmg]Mac鐗堝揩鎾�1.1.26 瀹樻柟姝e紡鐗圼dmg]
Mac璇诲啓NTFS(Paragon NTFS for Mac)12.1.62 瀹樻柟姝e紡鐗�Mac璇诲啓NTFS(Paragon NTFS for Mac)12.1.62 瀹樻柟姝e紡鐗�
杩呴浄10 for macv3.4.1.4368 瀹樻柟鏈€鏂扮増杩呴浄10 for macv3.4.1.4368 瀹樻柟鏈€鏂扮増
Mac涓嬫渶寮哄ぇ鐨勭郴缁熸竻鐞嗗伐鍏�(CleanMyMac for mac)v3.1.1 姝e紡鐗�Mac涓嬫渶寮哄ぇ鐨勭郴缁熸竻鐞嗗伐鍏�(CleanMyMac for mac)v3.1.1 姝e紡鐗�
鑻规灉BootCamp5.1.5640 瀹樻柟鏈€鏂扮増鑻规灉BootCamp5.1.5640 瀹樻柟鏈€鏂扮増

首頁編程開發(fā)Delphi → 多線程的基本概念和Delphi線程對象Tthread介紹

多線程的基本概念和Delphi線程對象Tthread介紹

相關(guān)文章發(fā)表評論 來源:西西整理時間:2013/3/4 9:32:27字體大�。�A-A+

作者:西西點(diǎn)擊:0次評論:0次標(biāo)簽: 多線程

  • 類型:服務(wù)器區(qū)大小:21KB語言:中文 評分:6.6
  • 標(biāo)簽:
立即下載

WIN 98/NT/2000/XP是個多任務(wù)操作系統(tǒng),也就是:一個進(jìn)程可以劃分為多個線程,每個線程輪流占用CPU運(yùn)行時間和資源,或者說,把CPU 時間劃成片,每個片分給不同的線程,這樣,每個線程輪流的“掛起”和“喚醒”,由于時間片很小,給人的感覺是同時運(yùn)行的。

多線程帶來如下好處:
1)避免瓶頸;
2)并行操作;
3)提高效率;

多線程的兩個概念:
1) 進(jìn)程:也稱任務(wù),程序載入內(nèi)存,并分配資源,稱為“一個進(jìn)程”。
注意:進(jìn)程本身并不一定要正在執(zhí)行。進(jìn)程由以下幾部分組成:
a>一個私有的地址空間,它是進(jìn)程可以使用的一組虛擬內(nèi)存地址空間;
b>程序的相關(guān)代碼、數(shù)據(jù)源;
c>系統(tǒng)資源,比如操作系統(tǒng)同步對象等;
d>至少包含一個線程(主線程);

2) 線程:是進(jìn)程的執(zhí)行單位(線程本身并不包括程序代碼,真正擁有代碼的是進(jìn)程),是操作系統(tǒng)分配CPU時間的基本實(shí)體,每個進(jìn)程至少包括一個線程,稱為主線程。一個進(jìn)程如果有多個線程,就可以共享同一進(jìn)程的資源,并可以并發(fā)執(zhí)行。通俗點(diǎn)說就是進(jìn)程中一段并發(fā)運(yùn)行的代碼(一個函數(shù)或過程)。

線程主要由如下兩部分組成:
a>數(shù)據(jù)結(jié)構(gòu);
b>CPU 寄存器和堆棧;

線程函數(shù)運(yùn)行,啟動函數(shù)就返回了,主線程繼續(xù)向下執(zhí)行,而線程函數(shù)在一個獨(dú)立的線程中執(zhí)行,它要執(zhí)行多久,什么時候返回,主線程是不管也不知道的。

一、Delphi線程對象--- Tthread

雖然Windows提供了較多的多線程設(shè)計的API 函數(shù),但是直接使用API 函數(shù)極其不方便,而且使用不當(dāng)還容易出錯。為解決這個問題,Borland公司率先推出了一種Tthread 對象,來解決多線程設(shè)計上的困難,簡化了多線程問題的處理。

一、Tthread對象的主要方法

構(gòu)造線程:

constructor Create(CreateSuspended:boolean)

CreateSuspended=true構(gòu)造但不喚醒 ;false構(gòu)造的同時即喚醒 。

掛起線程:
suspend:(把線程掛起的次數(shù)加一)


喚醒線程:
resume :(注意:注意這個屬性是把線程掛起的次數(shù)減一,當(dāng)次數(shù)為0時,即喚醒。也就是說,線程掛起多少次,喚醒也需要多少次。同時掛起的時候?qū)⒈3志€程的地址指針不變,所以線程掛起后再喚醒,將從掛起的地方開始運(yùn)行)

析構(gòu)(清除線程所占用的內(nèi)存):
destroy

終止線程
Terminate 

使用這個類也很簡單,基本用法是:先從TThread派生一個自己的線程類(因?yàn)門Thread
是一個抽象類,不能生成實(shí)例),然后是覆蓋(Override)抽象方法:Execute(這就是線程函數(shù),也就是在線程中執(zhí)行的代碼部分),如果需要用到可視VCL對象,還需要通過Synchronize過程進(jìn)行。

線程的終止和退出:

1)自動退出:

一個線程從Execute()過程中退出,即意味著線程的終止,此時將調(diào)用Windows的ExitThread()函數(shù)來清除線程所占用的堆棧。

如果線程對象的 FreeOnTerminate屬性設(shè)為True,則線程對象將自動刪除,并釋放線程所占用的資源。
這是消除線程對象最簡單的辦法。

2)受控退出:

利用線程對象的Terminate屬性,可以由進(jìn)程或者由其他線程控制線程的退出。只需要簡單的調(diào)用該線程的Terminate方法,并設(shè)置線程對象的Terminate屬性為True。
  一般來說,在線程中,應(yīng)該不斷監(jiān)視Terminate的值,一旦發(fā)現(xiàn)為True,則退出,一般來說,例如在Execute()過程中可以這樣寫:

While not Terminate do 
begin 
........ 
end;

3)退出的API函數(shù):

關(guān)于線程退出的API函數(shù)聲明如下:

Function TerminateThread(hThread:Thandle;dwExitCode:DWORD);

不過,這個函數(shù)會使代碼立刻終止,而不管程序中有沒有

try....finally

機(jī)制,可能會導(dǎo)致錯誤,不到萬不得已,最好不要使用。

4)利用掛起線程的方法(suspend)

利用掛起線程的suspend方法,后面跟個Free,也可以釋放線程,
例如:

thread1.suspend; //掛起

thread2.free; //釋放

二、多線程的同步機(jī)制

同步機(jī)制,研究多線程的同步機(jī)制的必要性在于,多線程同步工作時,如果同時調(diào)用相同的資源,就可能會出現(xiàn)問題,如對全局變量、數(shù)據(jù)庫操作發(fā)生沖突,甚至產(chǎn)生死鎖和競爭問題。

舉個發(fā)生沖突的實(shí)例看一下:

一般來說,對內(nèi)存數(shù)據(jù)加一的操作分解以后有三個步驟:
1、從內(nèi)存中讀出數(shù)據(jù)
2、數(shù)據(jù)加一
3、存入內(nèi)存
現(xiàn)在假設(shè)在一個兩個線程的應(yīng)用中用Inc進(jìn)行加一操作可能出現(xiàn)的一種情況:
1、線程A從內(nèi)存中讀出數(shù)據(jù)(假設(shè)為3)
2、線程B從內(nèi)存中讀出數(shù)據(jù)(也是3)
3、線程A對數(shù)據(jù)加一(現(xiàn)在是4)
4、線程B對數(shù)據(jù)加一(現(xiàn)在也是4)
5、線程A將數(shù)據(jù)存入內(nèi)存(現(xiàn)在內(nèi)存中的數(shù)據(jù)是4)
6、線程B也將數(shù)據(jù)存入內(nèi)存(現(xiàn)在內(nèi)存中的數(shù)據(jù)還是4,但兩個線程都對它加了一,應(yīng)該是5才對,所以這里出現(xiàn)了錯誤的結(jié)果)

1.臨界區(qū)(Critical Sections)

臨界區(qū)(CriticalSection)是一項共享數(shù)據(jù)訪問保護(hù)的技術(shù)。對它只有兩個操作:Enter和Leave,這兩個操作也是原子操作。

它的保護(hù)原理是這樣的:當(dāng)一個線程A調(diào)用某一個Enter后,開始訪問某個數(shù)據(jù)D,如果此時另一個線程B也要訪問數(shù)據(jù)D,則它會在調(diào)用這個Enter時,發(fā)現(xiàn)已經(jīng)有線程進(jìn)入臨界區(qū),然后線程B就會被掛起,等待線程A調(diào)用Leave。當(dāng)線程A完成操作,調(diào)用Leave離開后,線程B就會被喚醒,并設(shè)置臨界區(qū)標(biāo)志,開始操作數(shù)據(jù),這樣就防止了訪問沖突

var
CS:TRTLCriticalSection;//被聲明在程序最上方,作為線程都可以使用的全局變量。
initializeCriticalSection(cs); //初始化

Procedure InterlockedIncrement( var aValue : Integer );
Begin
  
    EnterCriticalSection(CS);//獨(dú)占
    Inc( aValue );
    LeaveCriticalSection(CS); //解除獨(dú)占
End;

現(xiàn)在再來看前面那個例子:
1. 線程A進(jìn)入臨界區(qū)(假設(shè)數(shù)據(jù)為3)
2. 線程B進(jìn)入臨界區(qū),因?yàn)锳已經(jīng)在臨界區(qū)中,所以B被掛起
3. 線程A對數(shù)據(jù)加一(現(xiàn)在是4)
4. 線程A離開臨界區(qū),喚醒線程B(現(xiàn)在內(nèi)存中的數(shù)據(jù)是4)
5. 線程B被喚醒,對數(shù)據(jù)加一(現(xiàn)在就是5了)
6. 線程B離開臨界區(qū),現(xiàn)在的數(shù)據(jù)就是正確的了。
臨界區(qū)就是這樣保護(hù)共享數(shù)據(jù)的訪問

請注意,臨界區(qū)只能在一個進(jìn)程內(nèi)使用,可以在多處設(shè)置調(diào)用enter。

不要長時間鎖住一份資源,如果你一直讓資源被鎖定,你就會阻止其它線程的執(zhí)行,并把整個程序帶到一個完全停止的狀態(tài),所以千萬不要在一個ciritical section中調(diào)用sleep()或任何Wait…()函數(shù)。

ciritical section的一個缺點(diǎn)是,它不是核心對象,如果進(jìn)入ciritical section的那個線程結(jié)束了或者當(dāng)?shù)袅耍鴽]有調(diào)用LeaveCriticalSection的話,系統(tǒng)沒有辦法將該ciritical section清除,如果你需要這樣的機(jī)能,你應(yīng)該使用mutex。

VOID InitializeCriticalSection(

  LPCRITICAL_SECTION lpCriticalSection//一個指針,指向欲被初始化的CRITICAL_SECTION變量

  );

函數(shù)功能:初始化一個臨界對象,當(dāng)你用畢臨界對象時,必須調(diào)用DeleteCriticalSection()清除它。

VOID DeleteCriticalSection (
LPCRITICAL_SECTION lpCriticalSection// 臨界對象指針  
);

函數(shù)功能:申請刪除臨界對象

VOID EnterCriticalSection(

  LPCRITICAL_SECTION lpCriticalSection//臨界對象指針

  );

函數(shù)功能:申請進(jìn)入臨界對象

VOID LeaveCriticalSection(

  LPCRITICAL_SECTION lpCriticalSection//臨界對象指針

  );

函數(shù)功能

申請進(jìn)入臨界對象

2.互斥器(Mutexes)

一個時間內(nèi)只能夠有一個線程擁有mutex,就好像同一個時間只能夠有一個線程進(jìn)入同一臨界區(qū)。

Mutex和critical section還是有差別的:

1.鎖住一個未被使用的Mutexes,比鎖住一個未被使用的critical section,需要花費(fèi)幾乎100倍的時間

2. Mutexes可以跨進(jìn)程使用,critical section則只能夠在同一個進(jìn)程中使用

3.等待一個Mutexes時,你可以指定結(jié)束等待的時間長度,但對于critical section則不行。

兩種對象的相關(guān)函數(shù)比較:

CRITICAL_SECTIONMutex核心對象
InitializeCriticalSection()CreateMutex()
 OpenMutex()
EnterCriticalSection()WaitForSingleObject()
 WaitForMultipleObject()
 MsgWaitForMutipleObjects()
LeaveCriticalSection()ReleaseMutex()
DeleteCriticalSection()CloseHandle()

Mutex的使用機(jī)制:

1.      有一個mutex,此時沒有任何線程擁有它,此時它處于非激發(fā)狀態(tài)。

2.      某個線程調(diào)用WaitforSingleObject()或任何其它的wait…函數(shù),并指定該mutex的handle為參數(shù)

3.      win32于是將該mutex的擁有權(quán)給予這個線程,然后將此mutex設(shè)為激發(fā)狀態(tài),于是wait..函數(shù)返回

4.      wait..函數(shù)返回后,win32立刻又將mutex設(shè)為非激發(fā)狀態(tài),是任何處于等待狀態(tài)下的其它線程沒有辦法獲得其擁有權(quán)

5.      獲得該mutex的線程調(diào)用Release,將mutex釋放掉。于是循環(huán)到第一步。

如果線程擁有一個mutex,而在結(jié)束前沒有調(diào)用releaseMutex,mutex不會被摧毀,該mutex會被win32視為“未被擁有”以及“未被激發(fā)”,下一個等待中的線程會被以WAIT_ABANDONED_0通知。如果是WaitForMultipleObjects()等待辭mutex,函數(shù)返回值介于WAIT_ABANDONED_0和WAIT_ABANDONED_0+n之間,n是指handle數(shù)組的元素個數(shù)。

HANDLE CreateMutex(
 LPSECURITY_ATTRIBUTES lpMutexAttributes,
 BOOL bInitialOwner,
 LPCTSTR lpName
);

參數(shù)  

lpMutexAttributes:安全屬性。Null表示使用默認(rèn)的屬性。

bInitialOwner:如果你希望調(diào)用這個函數(shù)的線程擁有mutex,就將此值設(shè)為true

lpName:互斥對象的名稱

返回值

 如果成功,則返回一個handle,否則返回null。

函數(shù)說明:

如果指定的mutex名稱已經(jīng)存在,win32會給你一個mutex handle,而不會為你產(chǎn)生一個新的mutex。調(diào)用GetLastError會傳回ERROR_ALREADY_EXISTS。當(dāng)你不需要mutex時,你可以調(diào)用closehandle()將它關(guān)閉。

BOOL ReleaseMutex(

HANDLE hMutex //欲釋放mutex的handle

);

返回值

 如果成功,則返回true,否則返回false。

3.信號量(Semaphores)

Mutex是semaphore的一種退化,如果你產(chǎn)生一個semaphore并令最大值為1,那它就是個mutex。因此,mutex又常被稱為binary semaphore。在許多系統(tǒng)中,semaphore常被使用,因?yàn)閙utex可能并不存在,在win32中semaphore被使用的情況就少得多,因?yàn)閙utex存在的原因。

一旦semaphore的現(xiàn)值降到0,就表示資源已經(jīng)耗盡。此時任何線程如果調(diào)用Wait…函數(shù),必然要等待,直到某個鎖定被解除。

HANDLE CreateSemaphore(

LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

 LONG lInitialCount,

LONG lMaximumCount,

 LPCTSTR lpName  

)

參數(shù):

lpSemaphoreAttributes:安全屬性,null表示使用默認(rèn)屬性。

lInitialCount:初始值,必須>=0,并且<= lMaximumCount

lMaximumCount:最大值,也就是在同一時間內(nèi)能夠鎖住semaphore的線程數(shù)

lpName:名稱,這個值也可以是null。

返回值:

 如果成功就返回一個handle,否則返回null。如果semaphore名稱已經(jīng)存在,函數(shù)還是會成功,GetLastError會返回ERROR_ALREADY_EXISTS

函數(shù)說明:

產(chǎn)生一個semaphore。

BOOL ReleaseSemaphore(

HANDLE hSemaphore,

LONG lReleaseCount,

LPLONG lpPreviousCount

);

參數(shù):

hSemaphore:semaphore的句柄。

lReleaseCount:semaphore現(xiàn)值的增量,通常是1,該值不可以是負(fù)值或者0

lpPreviousCount:返回semaphore增加前的現(xiàn)值

返回值:

 如果成功就返回true,否則返回false。

函數(shù)說明:

三、事件(Events)

事件(Event)是一種核心對象,它的唯一目的就是成為激發(fā)狀態(tài)或未激發(fā)狀態(tài)。這兩種狀態(tài)完全在你的掌握之下,不會因?yàn)閃ait…函數(shù)的調(diào)用而變化。

HANDLE     CreateEvent(   
      LPSECURITY_ATTRIBUTES       lpEventAttributes,        
      BOOL       bManualReset,                                                  
      BOOL       bInitialState,   

      LPCTSTR       lpName      

      );       

參數(shù):

     lpEventAttributes:安全屬性,null表示使用默認(rèn)屬性。

     bManualReset :

此值為false,表示event變成激發(fā)狀態(tài)后,自動重置為非激發(fā)狀態(tài);

此值為true,表示不會自動重置,必須靠程序(調(diào)用ResetEvent)操作才能將激發(fā)狀態(tài)的event重置為非激發(fā)狀態(tài)。

  bInitialState :初始狀態(tài),true一開始處于激發(fā)狀態(tài),false一開始處于非激發(fā)狀態(tài)

   lpName :Event對象名   

返回值:

如果成功就返回一個handle,否則返回null。如果event名稱已經(jīng)存在,函數(shù)還是會成功,GetLastError會返回ERROR_ALREADY_EXISTS

BOOL SetEvent(HANDLE hEvent);

//把event對象設(shè)為激發(fā)狀態(tài)

BOOL ResetEvent(HANDLE hEvent);

//把event對象設(shè)為非激發(fā)狀態(tài)

BOOL PulseEvent(HANDLE hEvent );

//如果event的bManualReset 為true:把event對象設(shè)為激發(fā)狀態(tài),喚醒所有等待中的線程,然后event恢復(fù)為非激發(fā)狀態(tài)

//如果event的bManualReset 為false:把event對象設(shè)為激發(fā)狀態(tài),喚醒一個等待中的線程,然后event恢復(fù)為非激發(fā)狀態(tài)

5.使用Synchronize方法

這個方法用于訪問VCL主線程所管理的資源,其方法的應(yīng)用是:
第一步:把訪問主窗口(或主窗口控件資源)的代碼放到線程的一個方法中;
第二步:是在線程對象的Execute方法中,通過Synchronize方法使用該方法。
實(shí)例:
procedure Theater.Execute; 
begin 
Synchronize(update); 
end; 

procedure Theater.update; 
begin 
......... 
end; 

這里通過 Synchronize使線程方法update同步。

6、使用VCL類的Look方法

在Delphi的IDE提供的構(gòu)件中,有一些對象內(nèi)部提供了線程的同步機(jī)制,工作線程可以直接使用這些控件,比如:Tfont,Tpen,TBitmap,TMetafile,Ticon等。另外,一個很重要的控件對象叫TCanvas,提供了一個Lock方法用于線程的同步,當(dāng)一個線程使用此控件對象的時候,首先調(diào)用這個對象的Lock方法,然后對這個控件進(jìn)行操作,完畢后再調(diào)用Unlock方法,釋放對控間的控制權(quán)。
例如:
CanversObject.look; 
try 
畫圖
finally 
CanversObject.unlock; 
end; 
{使用這個保護(hù)機(jī)制,保證不論有沒有異常,unlock都會被執(zhí)行否則很可能會發(fā)生死鎖。在多線程設(shè)計的時候,應(yīng)該很注意發(fā)生死鎖的問題}  

四、線程的優(yōu)先級:

在多線程的情況下,一般要根據(jù)線程執(zhí)行任務(wù)的重要性,給線程適當(dāng)?shù)膬?yōu)先級,一般如果量的線程同時申請CPU時間,優(yōu)先級高的線程優(yōu)先。

優(yōu)先權(quán)類別(Priority Class)

Win32提供四種優(yōu)先權(quán)類別,每一個類別對應(yīng)一個基本的優(yōu)先權(quán)層次。

表格5-1優(yōu)先權(quán)類別

優(yōu)先權(quán)類別基礎(chǔ)優(yōu)先權(quán)值
HIGH_PRIORITY_CLASS13
IDLE_PRIORITY_CLASS4
NORMAL_PRIORITY_CLASS7or8
REALTIME_PRIORITY_CLASS24

大部分程序使用NORMAL_PRIORITY_CLASS。優(yōu)先權(quán)類別是進(jìn)程的屬性之一,利用SetPriorityClass和GetPriorityClass函數(shù)可以調(diào)整和獲取該值。

優(yōu)先權(quán)層次(priority Level)

線程的優(yōu)先權(quán)層次使你能夠調(diào)整同一個進(jìn)程內(nèi)的各線程的相對重要性。一共七種優(yōu)先權(quán)層次:

表格5-2

優(yōu)先權(quán)層次調(diào)整值
THREAD_PRIORITY_LOWEST-2
THREAD_PRIORITY_BELOW_NORMAL-1
THREAD_PRIORITY_NORMAL0
THREAD_PRIORITY_ABOVE_NORMAL+1
THREAD_PEIOEITY_HIGHEST+2
THREAD_PRIORITY_IDLE1
THREAD_PRIORITY_TIME_CRITICAL15

利用SetThreadPriority和GetThreadPriority函數(shù)可以調(diào)整和獲取該值

在Windows下,給線程的優(yōu)先級分為30級,而Delphi中Tthread對象相對簡單的把優(yōu)先級分為七級。也就是在Tthread中聲明了一個枚舉類型TTthreadPriority:

type 
TTthreadPriority(tpidle,tpLowest,tpLower,tpNormal, 
tpHight,tpHighest,tpTimecrital) 

分別對應(yīng)的是最低(系統(tǒng)空閑時有效,-15),較低(-2),低(-1),正常(普通0),高(1),較高(2),最高(15)。
設(shè)置優(yōu)先級可使用thread對象的priority屬性:
threadObject.priority:=Tthreadpriority(級別);


BOOL SetThreadPriority(

HANDLE hThread,  //欲調(diào)整優(yōu)先權(quán)的那個線程的句柄

int nPriority         //表格5-2所顯示的值

);

Int GetThreadPriority(

   HANDLE hThread   //線程的句柄

    );

返回值是線程的優(yōu)先級。

    相關(guān)評論

    閱讀本文后您有什么感想? 已有人給出評價!

    • 8 喜歡喜歡
    • 3 頂
    • 1 難過難過
    • 5 囧
    • 3 圍觀圍觀
    • 2 無聊無聊

    熱門評論

    最新評論

    發(fā)表評論 查看所有評論(0)

    昵稱:
    表情: 高興 可 汗 我不要 害羞 好 下下下 送花 屎 親親
    字?jǐn)?shù): 0/500 (您的評論需要經(jīng)過審核才能顯示)
    推薦文章

    沒有數(shù)據(jù)