锘??xml version="1.0" encoding="utf-8" standalone="yes"?> Delphi涓殑綰跨▼綾宦?br />聽 Delphi涓湁涓涓嚎紼嬬被TThread鏄敤鏉ュ疄鐜板綰跨▼緙栫▼鐨勶紝榪欎釜緇濆ぇ澶氭暟Delphi涔﹁棄閮芥湁璇村埌錛屼絾鍩烘湰涓婇兘鏄 TThread綾葷殑鍑犱釜鎴愬憳浣滀竴綆鍗曚粙緇嶏紝鍐嶈鏄庝竴涓婨xecute鐨勫疄鐜板拰Synchronize鐨勭敤娉曞氨瀹屼簡銆傜劧鑰岃繖騫朵笉鏄綰跨▼緙?br />紼嬬殑鍏ㄩ儴錛屾垜鍐欐鏂囩殑鐩殑鍦ㄤ簬瀵規(guī)浣滀竴涓ˉ鍏呫?/p> 綰跨▼鏈川涓婃槸榪涚▼涓竴孌靛茍鍙戣繍琛岀殑浠g爜銆備竴涓繘紼嬭嚦灝戞湁涓涓嚎紼嬶紝鍗蟲墍璋撶殑涓葷嚎紼嬨傚悓鏃惰繕鍙互鏈夊涓瓙綰跨▼銆?br />褰撲竴涓繘紼嬩腑鐢ㄥ埌瓚呰繃涓涓嚎紼嬫椂錛屽氨鏄墍璋撶殑鈥滃綰跨▼鈥濄?br />閭d箞榪欎釜鎵璋撶殑鈥滀竴孌典唬鐮佲濇槸濡備綍瀹氫箟鐨勫憿錛熷叾瀹炲氨鏄竴涓嚱鏁版垨榪囩▼錛堝Delphi鑰岃█錛夈?br />濡傛灉鐢╓indows API鏉ュ垱寤虹嚎紼嬬殑璇濓紝鏄氳繃涓涓彨鍋欳reateThread鐨凙PI鍑芥暟鏉ュ疄鐜扮殑錛屽畠鐨勫畾涔変負(fù)錛?br />HANDLE CreateThread( 鍏跺悇鍙傛暟濡傚畠浠殑鍚嶇О鎵璇達紝鍒嗗埆鏄細綰跨▼灞炴э紙鐢ㄤ簬鍦∟T涓嬭繘琛岀嚎紼嬬殑瀹夊叏灞炴ц緗紝鍦?X涓嬫棤鏁堬級錛屽爢鏍堝ぇ灝忥紝 鍥犱負(fù)CreateThread鍙傛暟寰堝錛岃屼笖鏄疻indows鐨凙PI錛屾墍浠ュ湪C Runtime Library閲屾彁渚涗簡涓涓氱敤鐨勭嚎紼嬪嚱鏁幫紙鐞嗚涓?br />鍙互鍦ㄤ換浣曟敮鎸佺嚎紼嬬殑OS涓嬌鐢級錛?br />unsigned long _beginthread(void (_USERENTRY *__start)(void *), unsigned __stksize, void *__arg); Delphi涔熸彁渚涗簡涓涓浉鍚屽姛鑳界殑綾諱技鍑芥暟錛?br />function BeginThread( 聽 榪欎笁涓嚱鏁扮殑鍔熻兘鏄熀鏈浉鍚岀殑錛屽畠浠兘鏄皢綰跨▼鍑芥暟涓殑浠g爜鏀懼埌涓涓嫭绔嬬殑綰跨▼涓墽琛屻傜嚎紼嬪嚱鏁頒笌涓鑸嚱鏁扮殑 Windows API錛?br />VOID ExitThread( DWORD dwExitCode ); C Runtime Library錛?br />void _endthread(void); Delphi Runtime Library錛?br />procedure EndThread(ExitCode: Integer); 涓轟簡璁板綍涓浜涘繀瑕佺殑綰跨▼鏁版嵁錛堢姸鎬?灞炴х瓑錛夛紝OS浼氫負(fù)綰跨▼鍒涘緩涓涓唴閮∣bject錛屽鍦╓indows涓偅涓狧andle渚挎槸榪?br />涓唴閮∣bject鐨凥andle錛屾墍浠ュ湪綰跨▼緇撴潫鐨勬椂鍊欒繕搴旇閲婃斁榪欎釜Object銆?/p> 铏界劧璇寸敤API鎴朢TL(Runtime Library)宸茬粡鍙互寰堟柟渚垮湴榪涜澶氱嚎紼嬬紪紼嬩簡錛屼絾鏄繕鏄渶瑕佽繘琛岃緝澶氱殑緇嗚妭澶勭悊錛屼負(fù)姝?br />Delphi鍦–lasses鍗曞厓涓綰跨▼浣滀簡涓涓緝濂界殑灝佽錛岃繖灝辨槸VCL鐨勭嚎紼嬬被錛歍Thread 鏈枃鎺ヤ笅鏉ヨ璁ㄨ鐨勬槸TThread綾繪槸濡備綍瀵圭嚎紼嬭繘琛屽皝瑁呯殑錛屼篃灝辨槸娣卞叆鐮旂┒涓涓婽Thread綾葷殑瀹炵幇銆傚洜涓哄彧鏄湡姝e湴 TThread = class TThread綾誨湪Delphi鐨凴TL閲岀畻鏄瘮杈冪畝鍗曠殑綾伙紝綾繪垚鍛樹篃涓嶅錛岀被灞炴ч兘寰堢畝鍗曟槑鐧斤紝鏈枃灝嗗彧瀵瑰嚑涓瘮杈冮噸瑕佺殑綾?br />鎴愬憳鏂規(guī)硶鍜屽敮涓鐨勪簨浠訛細OnTerminate浣滆緇嗗垎鏋愩?br />棣栧厛灝辨槸鏋勯犲嚱鏁幫細 鍚屾牱鏈変竴涓搴旂殑RemoveThread錛?br />procedure RemoveThread; 浠ュ姞涓涓轟緥鏉ヨ鏄庝簩鑰呭疄鐜扮粏鑺備笂鐨勪笉鍚岋細 聽 鑰岀敤InterlockIncrement榪囩▼鍒欐病鏈夎繖涓棶棰橈紝鍥犱負(fù)鎵璋撯滃師璇濇槸涓縐嶄笉鍙腑鏂殑鎿嶄綔錛屽嵆鎿嶄綔緋葷粺鑳戒繚璇佸湪涓涓?br />鈥滃師璇濇墽琛屽畬姣曞墠涓嶄細榪涜綰跨▼鍒囨崲銆傛墍浠ュ湪涓婇潰閭d釜渚嬪瓙涓紝鍙湁褰撶嚎紼婣鎵ц瀹屽皢鏁版嵁瀛樺叆鍐呭瓨鍚庯紝綰跨▼B鎵嶅彲 鍓嶉潰閭d釜渚嬪瓙涔熻鏄庝竴縐嶁滅嚎紼嬭闂啿紿佲濈殑鎯呭喌錛岃繖涔熷氨鏄負(fù)浠涔堢嚎紼嬩箣闂撮渶瑕佲滃悓姝モ濓紙Synchronize錛夛紝鍏充簬榪?br />涓紝鍦ㄥ悗闈㈣鍒板悓姝ユ椂榪樹細鍐嶈緇嗚璁恒?/p> 璇村埌鍚屾錛屾湁涓涓澶栬瘽錛氬姞鎷垮ぇ婊戦搧鍗㈠ぇ瀛︾殑鏁欐巿鏉庢槑鏇懼氨Synchronize涓璇嶅湪鈥滅嚎紼嬪悓姝モ濅腑琚瘧浣溾滃悓姝モ濇彁鍑?br />榪囧紓璁紝涓漢璁や負(fù)浠栬鐨勫叾瀹炲緢鏈夐亾鐞嗐傚湪涓枃涓滃悓姝モ濈殑鎰忔濇槸鈥滃悓鏃跺彂鐢熲濓紝鑰屸滅嚎紼嬪悓姝モ濈洰鐨勫氨鏄伩鍏嶈繖 鎵繙浜嗭紝鍥炲埌TThread鐨勬瀯閫犲嚱鏁頒笂錛屾帴涓嬫潵鏈閲嶈灝辨槸榪欏彞浜嗭細 鐜板湪鏉ョ湅TThread鐨勬牳蹇冿細綰跨▼鍑芥暟ThreadProc銆傛湁鎰忔濈殑鏄繖涓嚎紼嬬被鐨勬牳蹇冨嵈涓嶆槸綰跨▼鐨勬垚鍛橈紝鑰屾槸涓涓叏灞鍑芥暟 function ThreadProc(Thread: TThread): Integer; 鎵浠ヨ錛孍xecute灝辨槸綰跨▼綾諱腑鐨勭嚎紼嬪嚱鏁幫紝鎵鏈夊湪Execute涓殑浠g爜閮介渶瑕佸綋浣滅嚎紼嬩唬鐮佹潵鑰冭檻錛屽闃叉璁塊棶鍐茬獊絳夈?br />濡傛灉Execute鍙戠敓寮傚父錛屽垯閫氳繃AcquireExceptionObject鍙栧緱寮傚父瀵硅薄錛屽茍瀛樺叆綰跨▼綾葷殑FFatalException鎴愬憳涓?br />鏈鍚庢槸綰跨▼緇撴潫鍓嶅仛鐨勪竴浜涙敹灝懼伐浣溿傚眬閮ㄥ彉閲廎reeThread璁板綍浜嗙嚎紼嬬被鐨凢reeOnTerminated灞炴х殑璁劇疆錛岀劧鍚庡皢綰?br />紼嬭繑鍥炲艱緗負(fù)綰跨▼綾葷殑榪斿洖鍊煎睘鎬х殑鍊箋傜劧鍚庢墽琛岀嚎紼嬬被鐨凞oTerminate鏂規(guī)硶銆?/p> DoTerminate鏂規(guī)硶鐨勪唬鐮佸涓嬶細 寰堢畝鍗曪紝灝辨槸閫氳繃Synchronize鏉ヨ皟鐢–allOnTerminate鏂規(guī)硶錛岃孋allOnTerminate鏂規(guī)硶鐨勪唬鐮佸涓嬶紝灝辨槸綆鍗曞湴璋冪敤 鍥犱負(fù)OnTerminate浜嬩歡鏄湪Synchronize涓墽琛岀殑錛屾墍浠ユ湰璐ㄤ笂瀹冨茍涓嶆槸綰跨▼浠g爜錛岃屾槸涓葷嚎紼嬩唬鐮侊紙鍏蜂綋瑙佸悗闈㈠ 鎵ц瀹孫nTerminate鍚庯紝灝嗙嚎紼嬬被鐨凢Finished鏍囧織璁劇疆涓篢rue銆傛帴涓嬫潵鎵цSignalSyncEvent榪囩▼錛屽叾浠g爜濡備笅錛?br />procedure SignalSyncEvent; 涔熷緢綆鍗曪紝灝辨槸璁劇疆涓涓嬩竴涓叏灞Event錛歋yncEvent錛屽叧浜嶦vent鐨勪嬌鐢紝鏈枃灝嗗湪鍚庢枃璇﹁堪錛岃孲yncEvent鐨勭敤閫斿皢 鐒跺悗鏍規(guī)嵁FreeThread涓繚瀛樼殑FreeOnTerminate璁劇疆鍐沖畾鏄惁閲婃斁綰跨▼綾伙紝鍦ㄧ嚎紼嬬被閲婃斁鏃訛紝榪樻湁涓浜涗簺鎿嶄綔錛岃瑙佹帴 鍦ㄧ嚎紼嬪璞¤閲婃斁鍓嶏紝棣栧厛瑕佹鏌ョ嚎紼嬫槸鍚﹁繕鍦ㄦ墽琛屼腑錛屽鏋滅嚎紼嬭繕鍦ㄦ墽琛屼腑錛堢嚎紼婭D涓嶄負(fù)0錛屽茍涓旂嚎紼嬬粨鏉熸爣蹇楁湭璁?br />緗級錛屽垯璋冪敤Terminate榪囩▼緇撴潫綰跨▼銆俆erminate榪囩▼鍙槸綆鍗曞湴璁劇疆綰跨▼綾葷殑Terminated鏍囧織錛屽涓嬮潰鐨勪唬鐮侊細 procedure TThread.Terminate; 鎵浠ョ嚎紼嬩粛鐒跺繀欏葷戶緇墽琛屽埌姝e父緇撴潫鍚庢墠琛岋紝鑰屼笉鏄珛鍗崇粓姝㈢嚎紼嬶紝榪欎竴鐐硅娉ㄦ剰銆?/p> 鍦ㄨ繖閲岃涓鐐歸澶栬瘽錛氬緢澶氫漢閮介棶榪囨垜錛屽浣曟墠鑳解滅珛鍗斥濈粓姝㈢嚎紼嬶紙褰撶劧鏄寚鐢═Thread鍒涘緩鐨勭嚎紼嬶級銆傜粨鏋滃綋鐒舵槸 褰撶劧濡傛灉浣犱竴瀹氳鑳解滅珛鍗斥濋鍑虹嚎紼嬶紝閭d箞TThread綾諱笉鏄竴涓ソ鐨勯夋嫨錛屽洜涓哄鏋滅敤API寮哄埗緇堟綰跨▼鐨勮瘽錛屾渶緇?br />浼氬鑷碩Thread綰跨▼瀵硅薄涓嶈兘琚紜噴鏀撅紝鍦ㄥ璞℃瀽鏋勬椂鍑虹幇Access Violation銆傝繖縐嶆儏鍐典綘鍙兘鐢ˋPI鎴朢TL鍑芥暟鏉ュ垱 濡傛灉綰跨▼澶勪簬鍚姩鎸傝搗鐘舵侊紝鍒欏皢綰跨▼杞叆榪愯鐘舵侊紝鐒跺悗璋冪敤WaitFor榪涜絳夊緟錛屽叾鍔熻兘灝辨槸絳夊緟鍒扮嚎紼嬬粨鏉熷悗鎵嶇戶 綰跨▼緇撴潫鍚庯紝鍏抽棴綰跨▼Handle錛堟甯哥嚎紼嬪垱寤虹殑鎯呭喌涓婬andle閮芥槸瀛樺湪鐨勶級錛岄噴鏀炬搷浣滅郴緇熷垱寤虹殑綰跨▼瀵硅薄銆?br />鐒跺悗璋冪敤TObject.Destroy閲婃斁鏈璞★紝騫墮噴鏀懼凡緇忔崟鑾風(fēng)殑寮傚父瀵硅薄錛屾渶鍚庤皟鐢≧emoveThread鍑忓皬榪涚▼鐨勭嚎紼嬫暟銆?/p> 鍏跺畠鍏充簬Suspend/Resume鍙婄嚎紼嬩紭鍏堢駭璁劇疆絳夋柟闈紝涓嶆槸鏈枃鐨勯噸鐐癸紝涓嶅啀璧樿堪銆備笅闈㈣璁ㄨ鐨勬槸鏈枃鐨勫彟涓や釜閲嶇偣 浣嗘槸鍦ㄤ粙緇嶈繖涓や釜鍑芥暟涔嬪墠錛岄渶瑕佸厛浠嬬粛鍙﹀涓や釜綰跨▼鍚屾鎶鏈細浜嬩歡鍜屼復(fù)鐣屽尯銆?/p> 浜嬩歡錛圗vent錛変笌Delphi涓殑浜嬩歡鏈夋墍涓嶅悓銆備粠鏈川涓婅錛孍vent鍏跺疄鐩稿綋浜庝竴涓叏灞鐨勫竷?yōu)當(dāng)鍙橀噺銆傚畠鏈変袱涓祴鍊兼搷浣?br />錛歋et鍜孯eset錛岀浉褰撲簬鎶婂畠璁劇疆涓篢rue鎴朏alse銆傝屾鏌ュ畠鐨勫兼槸閫氳繃WaitFor鎿嶄綔榪涜銆傚搴斿湪Windows騫沖彴涓婏紝鏄笁 榪欎笁涓兘鏄師璇紝鎵浠vent鍙互瀹炵幇涓鑸竷?yōu)當(dāng)鍙橀噺涓嶈兘瀹炵幇鐨勫湪澶毦U跨▼涓殑搴旂敤銆係et鍜孯eset鐨勫姛鑳藉墠闈㈠凡緇忚榪囦簡 WaitFor鐨勫姛鑳芥槸媯鏌vent鐨勭姸鎬佹槸鍚︽槸Set鐘舵侊紙鐩稿綋浜嶵rue錛夛紝濡傛灉鏄垯绔嬪嵆榪斿洖錛屽鏋滀笉鏄紝鍒欑瓑寰呭畠鍙樹負(fù)Set 褰揈vent浠嶳eset鐘舵佸悜Set鐘舵佽漿鎹㈡椂錛屽敜閱掑叾瀹冪敱浜嶹aitFor榪欎釜Event鑰屾寕璧風(fēng)殑綰跨▼錛岃繖灝辨槸瀹冧負(fù)浠涔堝彨Event鐨勫師 褰撶劧鐢ㄤ竴涓彈淇濇姢錛堣涓嬮潰鐨勪復(fù)鐣屽尯浠嬬粛錛夌殑甯冨皵鍙橀噺涔熻兘瀹炵幇綾諱技鐨勫姛鑳斤紝鍙鐢ㄤ竴涓驚鐜鏌ユ甯冨皵鍊肩殑浠g爜鏉?br />浠f浛WaitFor鍗沖彲銆備粠鍔熻兘涓婅瀹屽叏娌℃湁闂錛屼絾瀹為檯浣跨敤涓氨浼氬彂鐜幫紝榪欐牱鐨勭瓑寰呬細鍗犵敤澶ч噺鐨凜PU璧勬簮錛岄檷浣庣郴緇?br />鎬ц兘錛屽獎鍝嶅埌鍒殑綰跨▼鐨勬墽琛岄熷害錛屾墍浠ユ槸涓嶇粡嫻庣殑錛屾湁鐨勬椂鍊欑敋鑷沖彲鑳戒細鏈夐棶棰樸傛墍浠ヤ笉寤鴻榪欐牱鐢ㄣ?/p> 涓寸晫鍖猴紙CriticalSection錛夊垯鏄竴欏瑰叡浜暟鎹闂繚鎶ょ殑鎶鏈傚畠鍏跺疄涔熸槸鐩稿綋浜庝竴涓叏灞鐨勫竷?yōu)當(dāng)鍙橀噺銆備絾瀵瑰畠鐨勬搷 鐢ㄤ復(fù)鐣屽尯淇濇姢鍏變韓鏁版嵁鐨勬柟娉曞緢綆鍗曪細鍦ㄦ瘡嬈¤璁塊棶鍏變韓鏁版嵁涔嬪墠璋冪敤Enter璁劇疆榪涘叆涓寸晫鍖烘爣蹇楋紝鐒跺悗鍐嶆搷浣滄暟鎹紝 浠ュ墠闈㈤偅涓狪nterlockedIncrement涓轟緥錛屾垜浠敤CriticalSection錛圵indows API錛夋潵瀹炵幇瀹冿細 鐜板湪鍐嶆潵鐪嬪墠闈㈤偅涓緥瀛愶細 涓寸晫鍖哄氨鏄繖鏍蜂繚鎶ゅ叡浜暟鎹殑璁塊棶銆?/p> 鍏充簬涓寸晫鍖虹殑浣跨敤錛屾湁涓鐐硅娉ㄦ剰錛氬嵆鏁版嵁璁塊棶鏃剁殑寮傚父鎯呭喌澶勭悊銆傚洜涓哄鏋滃湪鏁版嵁鎿嶄綔鏃跺彂鐢熷紓甯革紝灝嗗鑷碙eave鎿?br />浣滄病鏈夎鎵ц錛岀粨鏋滃皢浣挎湰搴旇鍞ら啋鐨勭嚎紼嬫湭琚敜閱掞紝鍙兘閫犳垚紼嬪簭鐨勬病鏈夊搷搴斻傛墍浠ヤ竴鑸潵璇達紝濡備笅闈㈣繖鏍蜂嬌鐢ㄤ復(fù) EnterCriticalSection 鏈鍚庤璇存槑鐨勬槸錛孍vent鍜孋riticalSection閮芥槸鎿嶄綔緋葷粺璧勬簮錛屼嬌鐢ㄥ墠閮介渶瑕佸垱寤猴紝浣跨敤瀹屽悗涔熷悓鏍烽渶瑕侀噴鏀俱傚 鐢變簬鍦═Thread涓兘鏄敤API鏉ユ搷浣淓vent鍜孋riticalSection鐨勶紝鎵浠ュ墠闈㈤兘鏄互API涓轟緥錛屽叾瀹濪elphi宸茬粡鎻愪緵浜嗗瀹?br />浠殑灝佽錛屽湪SyncObjs鍗曞厓涓紝鍒嗗埆鏄疶Event綾誨拰TCriticalSection綾匯傜敤娉曚篃涓庡墠闈㈢敤API鐨勬柟娉曠浉宸棤鍑犮傚洜涓?br />TEvent鐨勬瀯閫犲嚱鏁板弬鏁拌繃澶氾紝涓轟簡綆鍗曡搗瑙侊紝Delphi榪樻彁渚涗簡涓涓敤榛樿鍙傛暟鍒濆鍖栫殑Event綾伙細TSimpleEvent銆?/p> 欏轟究鍐嶄粙緇嶄竴涓嬪彟涓涓敤浜庣嚎紼嬪悓姝ョ殑綾伙細TMultiReadExclusiveWriteSynchronizer錛屽畠鏄湪SysUtils鍗曞厓涓畾涔夌殑 鏈変簡鍓嶉潰瀵笶vent鍜孋riticalSection鐨勫噯澶囩煡璇嗭紝鍙互姝e紡寮濮嬭璁篠ynchronize鍜學(xué)aitFor浜嗐?br />鎴戜滑鐭ラ亾錛孲ynchronize鏄氳繃灝嗛儴鍒嗕唬鐮佹斁鍒頒富綰跨▼涓墽琛屾潵瀹炵幇綰跨▼鍚屾鐨勶紝鍥犱負(fù)鍦ㄤ竴涓繘紼嬩腑錛屽彧鏈変竴涓富綰跨▼ procedure TThread.Synchronize(Method: TThreadMethod); 鍏朵腑FSynchronize鏄竴涓褰曠被鍨嬶細 鐢ㄤ簬榪涜綰跨▼鍜屼富綰跨▼涔嬮棿榪涜鏁版嵁浜ゆ崲錛屽寘鎷紶鍏ョ嚎紼嬬被瀵硅薄錛屽悓姝ユ柟娉曞強鍙戠敓鐨勫紓甯搞?br />鍦⊿ynchronize涓皟鐢ㄤ簡瀹冪殑涓涓噸杞界増鏈紝鑰屼笖榪欎釜閲嶈澆鐗堟湰姣旇緝鐗瑰埆錛屽畠鏄竴涓滅被鏂規(guī)硶鈥濄傛墍璋撶被鏂規(guī)硶錛屾槸涓縐?br />鐗規(guī)畩鐨勭被鎴愬憳鏂規(guī)硶錛屽畠鐨勮皟鐢ㄥ茍涓嶉渶瑕佸垱寤虹被瀹炰緥錛岃屾槸鍍忔瀯閫犲嚱鏁伴偅鏍鳳紝閫氳繃綾誨悕璋冪敤銆備箣鎵浠ヤ細鐢ㄧ被鏂規(guī)硶鏉ュ疄鐜?br />瀹冿紝鏄洜涓轟負(fù)浜嗗彲浠ュ湪綰跨▼瀵硅薄娌℃湁鍒涘緩鏃朵篃鑳借皟鐢ㄥ畠銆備笉榪囧疄闄呬腑鏄敤瀹冪殑鍙︿竴涓噸杞界増鏈紙涔熸槸綾繪柟娉曪級鍜屽彟涓 class procedure TThread.Synchronize(ASyncRec: PSynchronizeRecord); 榪欐浠g爜鐣ュ涓浜涳紝涓嶈繃涔熶笉綆楀お澶嶆潅銆?br />棣栧厛鏄垽鏂綋鍓嶇嚎紼嬫槸鍚︽槸涓葷嚎紼嬶紝濡傛灉鏄紝鍒欑畝鍗曞湴鎵ц鍚屾鏂規(guī)硶鍚庤繑鍥炪?br />濡傛灉涓嶆槸涓葷嚎紼嬶紝鍒欏噯澶囧紑濮嬪悓姝ヨ繃紼嬨?br />閫氳繃灞閮ㄥ彉閲廠yncProc璁板綍綰跨▼浜ゆ崲鏁版嵁錛堝弬鏁幫級鍜屼竴涓狤vent Handle錛屽叾璁板綍緇撴瀯濡備笅錛?br />TSyncProc = record 鐒跺悗鍒涘緩涓涓狤vent錛屾帴鐫榪涘叆涓寸晫鍖猴紙閫氳繃鍏ㄥ眬鍙橀噺ThreadLock榪涜錛屽洜涓哄悓鏃跺彧鑳芥湁涓涓嚎紼嬭繘鍏ynchronize鐘?br />鎬侊紝鎵浠ュ彲浠ョ敤鍏ㄥ眬鍙橀噺璁板綍錛夛紝鐒跺悗灝辨槸鎶婅繖涓褰曟暟鎹瓨鍏yncList榪欎釜鍒楄〃涓紙濡傛灉榪欎釜鍒楄〃涓嶅瓨鍦ㄧ殑璇濓紝鍒?br />鍒涘緩瀹冿級銆傚彲瑙乀hreadLock榪欎釜涓寸晫鍖哄氨鏄負(fù)浜嗕繚鎶ゅSyncList鐨勮闂紝榪欎竴鐐瑰湪鍚庨潰浠嬬粛CheckSynchronize鏃朵細鍐?br />嬈$湅鍒般?/p> 鍐嶆帴涓嬪氨鏄皟鐢⊿ignalSyncEvent錛屽叾浠g爜鍦ㄥ墠闈粙緇峊Thread鐨勬瀯閫犲嚱鏁版椂宸茬粡浠嬬粛榪囦簡錛屽畠鐨勫姛鑳藉氨鏄畝鍗曞湴灝?br />SyncEvent浣滀竴涓猄et鐨勬搷浣溿傚叧浜庤繖涓猄yncEvent鐨勭敤閫旓紝灝嗗湪鍚庨潰浠嬬粛WaitFor鏃跺啀璇﹁堪銆?/p> 鎺ヤ笅鏉ュ氨鏄渶涓昏鐨勯儴鍒嗕簡錛氳皟鐢╓akeMainThread浜嬩歡榪涜鍚屾鎿嶄綔銆俉akeMainThread鏄竴涓猅NotifyEvent綾誨瀷鐨勫叏 procedure TApplication.HookSynchronizeWakeup; procedure TApplication.UnhookSynchronizeWakeup; 涓婇潰涓や釜鏂規(guī)硶鍒嗗埆鏄湪TApplication綾葷殑鏋勯犲嚱鏁板拰鏋愭瀯鍑芥暟涓璋冪敤銆?br />榪欏氨鏄湪Application瀵硅薄涓璚akeMainThread浜嬩歡鍝嶅簲鐨勪唬鐮侊紝娑堟伅灝辨槸鍦ㄨ繖閲岃鍙戝嚭鐨勶紝瀹冨埄鐢ㄤ簡涓涓┖娑堟伅鏉ュ疄鐜幫細 procedure TApplication.WakeMainThread(Sender: TObject); 鑰岃繖涓秷鎭殑鍝嶅簲涔熸槸鍦ˋpplication瀵硅薄涓紝瑙佷笅闈㈢殑浠g爜錛堝垹闄ゆ棤鍏崇殑閮ㄥ垎錛夛細 鍏朵腑鐨凜heckSynchronize涔熸槸瀹氫箟鍦–lasses鍗曞厓涓殑錛岀敱浜庡畠姣旇緝澶嶆潅錛屾殏鏃朵笉璇︾粏璇存槑錛屽彧瑕佺煡閬撳畠鏄叿浣撳鐞?br />Synchronize鍔熻兘鐨勯儴鍒嗗氨濂斤紝鐜板湪緇х畫鍒嗘瀽Synchronize鐨勪唬鐮併?br />鍦ㄦ墽琛屽畬W(xué)akeMainThread浜嬩歡鍚庯紝灝遍鍑轟復(fù)鐣屽尯錛岀劧鍚庤皟鐢╓aitForSingleObject寮濮嬬瓑寰呭湪榪涘叆涓寸晫鍖哄墠鍒涘緩鐨勯偅涓?br />Event銆傝繖涓狤vent鐨勫姛鑳芥槸絳夊緟榪欎釜鍚屾鏂規(guī)硶鐨勬墽琛岀粨鏉燂紝鍏充簬榪欑偣錛屽湪鍚庨潰鍒嗘瀽CheckSynchronize鏃朵細鍐嶈鏄庛?br />娉ㄦ剰鍦╓aitForSingleObject涔嬪悗鍙堥噸鏂拌繘鍏ヤ復(fù)鐣屽尯錛屼絾娌℃湁鍋氫換浣曚簨灝遍鍑轟簡錛屼技涔庢病鏈夋剰涔夛紝浣嗚繖鏄繀欏葷殑錛?br />鍥犱負(fù)涓寸晫鍖虹殑Enter鍜孡eave蹇呴』涓ユ牸鐨勪竴涓瀵瑰簲銆傞偅涔堟槸鍚﹀彲浠ユ敼鎴愯繖鏍峰憿錛?/p> if Assigned(WakeMainThread) then 涓婇潰鐨勪唬鐮佸拰鍘熸潵鐨勪唬鐮佹渶澶х殑鍖哄埆鍦ㄤ簬鎶奧aitForSingleObject涔熺撼鍏ヤ復(fù)鐣屽尯鐨勯檺鍒朵腑浜嗐傜湅涓婂幓娌′粈涔堝獎鍝嶏紝榪樹嬌 鍥犱負(fù)鎴戜滑鐭ラ亾錛屽湪Enter涓寸晫鍖哄悗錛屽鏋滃埆鐨勭嚎紼嬭鍐嶈繘鍏ワ紝鍒欎細琚寕璧楓傝學(xué)aitFor鏂規(guī)硶鍒欎細鎸傝搗褰撳墠綰跨▼錛岀洿鍒扮瓑 鍥炲埌鍓嶉潰CheckSynchronize錛岃涓嬮潰鐨勪唬鐮侊細 function CheckSynchronize(Timeout: Integer = 0): Boolean; 棣栧厛錛岃繖涓柟娉曞繀欏誨湪涓葷嚎紼嬩腑琚皟鐢紙濡傚墠闈㈤氳繃娑堟伅浼犻掑埌涓葷嚎紼嬶級錛屽惁鍒欏氨鎶涘嚭寮傚父銆?br />鎺ヤ笅鏉ヨ皟鐢≧esetSyncEvent錛堝畠涓庡墠闈etSyncEvent瀵瑰簲鐨勶紝涔嬫墍浠ヤ笉鑰冭檻WaitForSyncEvent鐨勬儏鍐碉紝鏄洜涓哄彧鏈夊湪 鍐嶆潵鐪嬪鍚屾鏂規(guī)硶鐨勫鐞嗭細棣栧厛鏄粠鍒楄〃涓Щ鍑猴紙鍙栧嚭騫朵粠鍒楄〃涓垹闄わ級絎竴涓悓姝ユ柟娉曡皟鐢ㄦ暟鎹傜劧鍚庨鍑轟復(fù)鐣屽尯 鏈鍚庢潵璇翠竴涓媁aitFor錛屽畠鐨勫姛鑳藉氨鏄瓑寰呯嚎紼嬫墽琛岀粨鏉熴傚叾浠g爜濡備笅錛?br />function TThread.WaitFor: LongWord; 濡傛灉涓嶆槸鍦ㄤ富綰跨▼涓墽琛學(xué)aitFor鐨勮瘽錛屽緢綆鍗曪紝鍙璋冪敤WaitForSingleObject絳夊緟姝ょ嚎紼嬬殑Handle涓篠ignaled鐘舵?br />鍗沖彲銆?/p> 濡傛灉鏄湪涓葷嚎紼嬩腑鎵цW(xué)aitFor鍒欐瘮杈冮夯鐑︺傞鍏堣鍦℉andle鏁扮粍涓鍔犱竴涓猄yncEvent錛岀劧鍚庡驚鐜瓑寰咃紝鐩村埌綰跨▼緇?br />鏉燂紙鍗矼sgWaitForMultipleObjects榪斿洖WAIT_OBJECT_0錛岃瑙丮SDN涓叧浜庢API鐨勮鏄庯級銆?br />鍦ㄥ驚鐜瓑寰呬腑浣滃涓嬪鐞嗭細濡傛灉鏈夋秷鎭彂鐢燂紝鍒欓氳繃PeekMessage鍙栧嚭姝ゆ秷鎭紙浣嗗茍涓嶆妸瀹冧粠娑堟伅寰幆涓Щ闄わ級錛岀劧鍚?br />璋冪敤MsgWaitForMultipleObjects鏉ョ瓑寰呯嚎紼婬andle鎴朣yncEvent鍑虹幇Signaled鐘舵侊紝鍚屾椂鐩戝惉娑堟伅錛圦S_SENDMESSAGE
杞創(chuàng)浜?鍗庡榛戝鍚岀洘 http://www.77169.org
聽聽聽 LPSECURITY_ATTRIBUTES lpThreadAttributes,
聽聽聽 DWORD dwStackSize,
聽聽聽 LPTHREAD_START_ROUTINE lpStartAddress,
聽聽聽 LPVOID lpParameter,
聽聽聽 DWORD dwCreationFlags,
聽聽聽 LPDWORD lpThreadId
);
璧峰鍦板潃錛屽弬鏁幫紝鍒涘緩鏍囧織錛堢敤浜庤緗嚎紼嬪垱寤烘椂鐨勭姸鎬侊級錛岀嚎紼婭D錛屾渶鍚庤繑鍥炵嚎紼婬andle銆傚叾涓殑璧峰鍦板潃灝辨槸綰?br />紼嬪嚱鏁扮殑鍏ュ彛錛岀洿鑷崇嚎紼嬪嚱鏁扮粨鏉燂紝綰跨▼涔熷氨緇撴潫浜嗐?/p>
聽聽聽 SecurityAttributes: Pointer;
聽聽聽 StackSize: LongWord;
聽聽聽 ThreadFunc: TThreadFunc;
聽聽聽 Parameter: Pointer;
聽聽聽 CreationFlags: LongWord;
聽聽聽 var ThreadId: LongWord
): Integer;
鏈澶т笉鍚屽湪浜庯紝綰跨▼鍑芥暟涓鍚姩錛岃繖涓変釜綰跨▼鍚姩鍑芥暟灝辮繑鍥炰簡錛屼富綰跨▼緇х畫鍚戜笅鎵ц錛岃岀嚎紼嬪嚱鏁板湪涓涓嫭绔嬬殑綰?br />紼嬩腑鎵ц錛屽畠瑕佹墽琛屽涔咃紝浠涔堟椂鍊欒繑鍥烇紝涓葷嚎紼嬫槸涓嶇涔熶笉鐭ラ亾鐨勩?br />姝e父鎯呭喌涓嬶紝綰跨▼鍑芥暟榪斿洖鍚庯紝綰跨▼灝辯粓姝簡銆備絾涔熸湁鍏跺畠鏂瑰紡錛?/p>
浣跨敤榪欎釜綾諱篃寰堢畝鍗曪紝澶у鏁扮殑Delphi涔︾睄閮芥湁璇達紝鍩烘湰鐢ㄦ硶鏄細鍏堜粠TThread媧劇敓涓涓嚜宸辯殑綰跨▼綾伙紙鍥犱負(fù)TThread
鏄竴涓娊璞$被錛屼笉鑳界敓鎴愬疄渚嬶級錛岀劧鍚庢槸Override鎶借薄鏂規(guī)硶錛欵xecute錛堣繖灝辨槸綰跨▼鍑芥暟錛屼篃灝辨槸鍦ㄧ嚎紼嬩腑鎵ц鐨勪唬鐮?br />閮ㄥ垎錛夛紝濡傛灉闇瑕佺敤鍒板彲瑙哣CL瀵硅薄錛岃繕闇瑕侀氳繃Synchronize榪囩▼榪涜銆傚叧浜庝箣鏂歸潰鐨勫叿浣撶粏鑺傦紝榪欓噷涓嶅啀璧樿堪錛岃
鍙傝冪浉鍏充功綾嶃?/p>
浜嗚В浜嗗畠錛屾墠鏇村ソ鍦頒嬌鐢ㄥ畠銆?br />涓嬮潰鏄疍ELPHI7涓璗Thread綾葷殑澹版槑錛堟湰鏂囧彧璁ㄨ鍦╓indows騫沖彴涓嬬殑瀹炵幇錛屾墍浠ュ幓鎺変簡鎵鏈夋湁鍏矻inux騫沖彴閮ㄥ垎鐨勪唬鐮?br />錛夛細
private
聽聽聽 FHandle: THandle;
聽聽聽 FThreadID: THandle;
聽聽聽 FCreateSuspended: Boolean;
聽聽聽 FTerminated: Boolean;
聽聽聽 FSuspended: Boolean;
聽聽聽 FFreeOnTerminate: Boolean;
聽聽聽 FFinished: Boolean;
聽聽聽 FReturnValue: Integer;
聽聽聽 FOnTerminate: TNotifyEvent;
聽聽聽 FSynchronize: TSynchronizeRecord;
聽聽聽 FFatalException: TObject;
聽聽聽 procedure CallOnTerminate;
聽聽聽 class procedure Synchronize(ASyncRec: PSynchronizeRecord); overload;
聽聽聽 function GetPriority: TThreadPriority;
聽聽聽 procedure SetPriority(Value: TThreadPriority);
聽聽聽 procedure SetSuspended(Value: Boolean);
protected
聽聽聽 procedure CheckThreadError(ErrCode: Integer); overload;
聽聽聽 procedure CheckThreadError(Success: Boolean); overload;
聽聽聽 procedure DoTerminate; virtual;
聽聽聽 procedure Execute; virtual; abstract;
聽聽聽 procedure Synchronize(Method: TThreadMethod); overload;
聽聽聽 property ReturnValue: Integer read FReturnValue write FReturnValue;
聽聽聽 property Terminated: Boolean read FTerminated;
public
聽聽聽 constructor Create(CreateSuspended: Boolean);
聽聽聽 destructor Destroy; override;
聽聽聽 procedure AfterConstruction; override;
聽聽聽 procedure Resume;
聽聽聽 procedure Suspend;
聽聽聽 procedure Terminate;
聽聽聽 function WaitFor: LongWord;
聽聽聽 class procedure Synchronize(AThread: TThread; AMethod: TThreadMethod); overload;
聽聽聽 class procedure StaticSynchronize(AThread: TThread; AMethod: TThreadMethod);
聽聽聽 property FatalException: TObject read FFatalException;
聽聽聽 property FreeOnTerminate: Boolean read FFreeOnTerminate write FFreeOnTerminate;
聽聽聽 property Handle: THandle read FHandle;
聽聽聽 property Priority: TThreadPriority read GetPriority write SetPriority;
聽聽聽 property Suspended: Boolean read FSuspended write SetSuspended;
聽聽聽 property ThreadID: THandle read FThreadID;
聽聽聽 property OnTerminate: TNotifyEvent read FOnTerminate write FOnTerminate;
end;
constructor TThread.Create(CreateSuspended: Boolean);
begin
聽聽聽 inherited Create;
聽聽聽 AddThread;
聽聽聽 FSuspended := CreateSuspended;
聽聽聽 FCreateSuspended := CreateSuspended;
聽聽聽 FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
聽聽聽 if FHandle = 0 then
聽聽聽聽聽聽聽 raise EThread.CreateResFmt(@SThreadCreateError, [SysErrorMessage(GetLastError)]);
end;
铏界劧榪欎釜鏋勯犲嚱鏁版病鏈夊灝戜唬鐮侊紝浣嗗嵈鍙互綆楁槸鏈閲嶈鐨勪竴涓垚鍛橈紝鍥犱負(fù)綰跨▼灝辨槸鍦ㄨ繖閲岃鍒涘緩鐨勩?br />鍦ㄩ氳繃Inherited璋冪敤TObject.Create鍚庯紝絎竴鍙ュ氨鏄皟鐢ㄤ竴涓繃紼嬶細AddThread錛屽叾婧愮爜濡備笅錛?br />procedure AddThread;
begin
聽聽聽 InterlockedIncrement(ThreadCount);
end;
begin
聽聽聽 InterlockedDecrement(ThreadCount);
end;
瀹冧滑鐨勫姛鑳藉緢綆鍗曪紝灝辨槸閫氳繃澧炲噺涓涓叏灞鍙橀噺鏉ョ粺璁¤繘紼嬩腑鐨勭嚎紼嬫暟銆傚彧鏄繖閲岀敤浜庡鍑忓彉閲忕殑騫朵笉鏄父鐢ㄧ殑
Inc/Dec榪囩▼錛岃屾槸鐢ㄤ簡InterlockedIncrement/InterlockedDecrement榪欎竴瀵硅繃紼嬶紝瀹冧滑瀹炵幇鐨勫姛鑳藉畬鍏ㄤ竴鏍鳳紝閮芥槸
瀵瑰彉閲忓姞涓鎴栧噺涓銆備絾瀹冧滑鏈変竴涓渶澶х殑鍖哄埆錛岄偅灝辨槸InterlockedIncrement/InterlockedDecrement鏄嚎紼嬪畨鍏ㄧ殑銆?br />鍗沖畠浠湪澶氱嚎紼嬩笅鑳戒繚璇佹墽琛岀粨鏋滄紜紝鑰孖nc/Dec涓嶈兘銆傛垨鑰呮寜鎿嶄綔緋葷粺鐞嗚涓殑鏈鏉ヨ錛岃繖鏄竴瀵光滃師璇濇搷浣溿?/p>
涓鑸潵璇達紝瀵瑰唴瀛樻暟鎹姞涓鐨勬搷浣滃垎瑙d互鍚庢湁涓変釜姝ラ錛?br />1銆?浠庡唴瀛樹腑璇誨嚭鏁版嵁
2銆?鏁版嵁鍔犱竴
3銆?瀛樺叆鍐呭瓨
鐜板湪鍋囪鍦ㄤ竴涓袱涓嚎紼嬬殑搴旂敤涓敤Inc榪涜鍔犱竴鎿嶄綔鍙兘鍑虹幇鐨勪竴縐嶆儏鍐碉細
1銆?綰跨▼A浠庡唴瀛樹腑璇誨嚭鏁版嵁錛堝亣璁句負(fù)3錛?br />2銆?綰跨▼B浠庡唴瀛樹腑璇誨嚭鏁版嵁錛堜篃鏄?錛?br />3銆?綰跨▼A瀵規(guī)暟鎹姞涓錛堢幇鍦ㄦ槸4錛?br />4銆?綰跨▼B瀵規(guī)暟鎹姞涓錛堢幇鍦ㄤ篃鏄?錛?br />5銆?綰跨▼A灝嗘暟鎹瓨鍏ュ唴瀛橈紙鐜板湪鍐呭瓨涓殑鏁版嵁鏄?錛?br />6銆?綰跨▼B涔熷皢鏁版嵁瀛樺叆鍐呭瓨錛堢幇鍦ㄥ唴瀛樹腑鐨勬暟鎹繕鏄?錛屼絾涓や釜綰跨▼閮藉瀹冨姞浜嗕竴錛屽簲璇ユ槸5鎵嶅錛屾墍浠ヨ繖閲屽嚭鐜頒簡
閿欒鐨勭粨鏋滐級
浠ュ紑濮嬩粠涓彇鏁板茍榪涜鍔犱竴鎿嶄綔錛岃繖鏍峰氨淇濊瘉浜嗗嵆浣挎槸鍦ㄥ綰跨▼鎯呭喌涓嬶紝緇撴灉涔熶竴瀹氫細鏄紜殑銆?/p>
縐嶁滃悓鏃跺彂鐢熲濈殑浜嬫儏銆傝屽湪鑻辨枃涓紝Synchronize鐨勬剰鎬濇湁涓や釜錛氫竴涓槸浼犵粺鎰忎箟涓婄殑鍚屾錛圱o occur at the same
time錛夛紝鍙︿竴涓槸鈥滃崗璋冧竴鑷粹濓紙To operate in unison錛夈傚湪鈥滅嚎紼嬪悓姝モ濅腑鐨凷ynchronize涓璇嶅簲璇ユ槸鎸囧悗闈竴縐?br />鎰忔濓紝鍗斥滀繚璇佸涓嚎紼嬪湪璁塊棶鍚屼竴鏁版嵁鏃訛紝淇濇寔鍗忚皟涓鑷達紝閬垮厤鍑洪敊鈥濄備笉榪囧儚榪欐牱璇戝緱涓嶅噯鐨勮瘝鍦↖T涓氳繕鏈夊緢澶?br />錛屾棦鐒跺凡緇忔槸綰﹀畾淇楁垚浜嗭紝鏈枃涔熷皢緇х畫娌跨敤錛屽彧鏄湪榪欓噷璇存槑涓涓嬶紝鍥犱負(fù)杞歡寮鍙戞槸涓欏圭粏鑷寸殑宸ヤ綔錛岃寮勬竻妤氱殑
錛岀粷涓嶈兘鍚硦銆?/p>
FHandle := BeginThread(nil, 0, @ThreadProc, Pointer(Self), CREATE_SUSPENDED, FThreadID);
榪欓噷灝辯敤鍒頒簡鍓嶉潰璇村埌鐨凞elphi RTL鍑芥暟BeginThread錛屽畠鏈夊緢澶氬弬鏁幫紝鍏抽敭鐨勬槸絎笁銆佸洓涓や釜鍙傛暟銆傜涓変釜鍙傛暟灝辨槸
鍓嶉潰璇村埌鐨勭嚎紼嬪嚱鏁幫紝鍗沖湪綰跨▼涓墽琛岀殑浠g爜閮ㄥ垎銆傜鍥涗釜鍙傛暟鍒欐槸浼犻掔粰綰跨▼鍑芥暟鐨勫弬鏁幫紝鍦ㄨ繖閲屽氨鏄垱寤虹殑綰跨▼
瀵硅薄錛堝嵆Self錛夈傚叾瀹冪殑鍙傛暟涓紝絎簲涓槸鐢ㄤ簬璁劇疆綰跨▼鍦ㄥ垱寤哄悗鍗蟲寕璧鳳紝涓嶇珛鍗蟲墽琛岋紙鍚姩綰跨▼鐨勫伐浣滄槸鍦?br />AfterConstruction涓牴鎹瓹reateSuspended鏍囧織鏉ュ喅瀹氱殑錛夛紝絎叚涓槸榪斿洖綰跨▼ID銆?/p>
錛堝洜涓築eginThread榪囩▼鐨勫弬鏁扮害瀹氬彧鑳界敤鍏ㄥ眬鍑芥暟錛夈備笅闈㈡槸瀹冪殑浠g爜錛?/p>
var
聽聽聽 FreeThread: Boolean;
begin
聽聽聽聽聽 try
聽聽聽聽聽聽聽聽聽聽聽 if not Thread.Terminated then
聽聽聽聽聽聽聽聽聽聽聽 try
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Thread.Execute;
聽聽聽聽聽聽聽聽聽聽聽 except
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Thread.FFatalException := AcquireExceptionObject;
聽聽聽聽聽聽聽聽聽聽聽 end;
聽聽聽聽聽 finally
聽聽聽聽聽聽聽聽聽聽聽 FreeThread := Thread.FFreeOnTerminate;
聽聽聽聽聽聽聽聽聽聽聽 Result := Thread.FReturnValue;
聽聽聽聽聽聽聽聽聽聽聽 Thread.DoTerminate;
聽聽聽聽聽聽聽聽聽聽聽 Thread.FFinished := True;
聽聽聽聽聽聽聽聽聽聽聽 SignalSyncEvent;
聽聽聽聽聽聽聽聽聽聽聽 if FreeThread then Thread.Free;
聽聽聽聽聽聽聽聽聽聽聽 EndThread(Result);
聽聽聽聽聽 end;
end;
铏界劧涔熸病鏈夊灝戜唬鐮侊紝浣嗗嵈鏄暣涓猅Thread涓渶閲嶈鐨勯儴鍒嗭紝鍥犱負(fù)榪欐浠g爜鏄湡姝e湪綰跨▼涓墽琛岀殑浠g爜銆備笅闈㈠浠g爜浣?br />閫愯璇存槑錛?br />棣栧厛鍒ゆ柇綰跨▼綾葷殑Terminated鏍囧織錛屽鏋滄湭琚爣蹇椾負(fù)緇堟錛屽垯璋冪敤綰跨▼綾葷殑Execute鏂規(guī)硶鎵ц綰跨▼浠g爜錛屽洜涓篢Thread
鏄娊璞$被錛孍xecute鏂規(guī)硶鏄娊璞℃柟娉曪紝鎵浠ユ湰璐ㄤ笂鏄墽琛屾淳鐢熺被涓殑Execute浠g爜銆?/p>
procedure TThread.DoTerminate;
begin
聽聽聽 if Assigned(FOnTerminate) then Synchronize(CallOnTerminate);
end;
OnTerminate浜嬩歡錛?br />procedure TThread.CallOnTerminate;
begin
聽聽聽 if Assigned(FOnTerminate) then FOnTerminate(Self);
end;
Synchronize鐨勫垎鏋愶級銆?/p>
begin
聽聽聽 SetEvent(SyncEvent);
end;
鍦╓aitFor榪囩▼涓鏄庛?/p>
涓嬫潵鐨勬瀽鏋勫嚱鏁板疄鐜般?br />鏈鍚庤皟鐢‥ndThread緇撴潫綰跨▼錛岃繑鍥炵嚎紼嬭繑鍥炲箋傝嚦姝わ紝綰跨▼瀹屽叏緇撴潫銆?br />璇村畬鏋勯犲嚱鏁幫紝鍐嶆潵鐪嬫瀽鏋勫嚱鏁幫細
destructor TThread.Destroy;
begin
聽 if (FThreadID <> 0) and not FFinished then聽 begin
聽聽聽聽聽 Terminate;
聽聽聽聽聽 if FCreateSuspended then
聽聽聽聽聽聽聽聽聽 Resume;
聽聽聽聽聽 WaitFor;
聽 end;
聽 if FHandle <> 0 then CloseHandle(FHandle);
聽 inherited Destroy;
聽 FFatalException.Free;
聽 RemoveThread;
end;
begin
聽聽聽 FTerminated := True;
end;
涓嶈錛佺粓姝㈢嚎紼嬬殑鍞竴鍔炴硶灝辨槸璁〦xecute鏂規(guī)硶鎵ц瀹屾瘯錛屾墍浠ヤ竴鑸潵璇達紝瑕佽浣犵殑綰跨▼鑳藉灝藉揩緇堟錛屽繀欏誨湪
Execute鏂規(guī)硶涓湪杈冪煭鐨勬椂闂村唴涓嶆柇鍦版鏌erminated鏍囧織錛屼互渚胯兘鍙婃椂鍦伴鍑恒傝繖鏄璁$嚎紼嬩唬鐮佺殑涓涓緢閲嶈鐨勫師
鍒欙紒
寤虹嚎紼嬨?/p>
緇悜涓嬫墽琛屻傚叧浜嶹aitFor鐨勫疄鐜幫紝灝嗘斁鍒板悗闈㈣鏄庛?/p>
錛歋ynchronize鍜學(xué)aitFor銆?/p>
涓狝PI鍑芥暟錛歋etEvent銆丷esetEvent銆乄aitForSingleObject錛堝疄鐜癢aitFor鍔熻兘鐨凙PI榪樻湁鍑犱釜錛岃繖鏄渶綆鍗曠殑涓涓級銆?/p>
錛岀幇鍦ㄦ潵璇翠竴涓媁aitFor鐨勫姛鑳斤細
鐘舵侊紝鍦ㄧ瓑寰呮湡闂達紝璋冪敤WaitFor鐨勭嚎紼嬪浜庢寕璧風(fēng)姸鎬併傚彟澶朩aitFor鏈変竴涓弬鏁扮敤浜庤秴鏃惰緗紝濡傛灉姝ゅ弬鏁頒負(fù)0錛屽垯涓?br />絳夊緟錛岀珛鍗寵繑鍥濫vent鐨勭姸鎬侊紝濡傛灉鏄疘NFINITE鍒欐棤闄愮瓑寰咃紝鐩村埌Set鐘舵佸彂鐢燂紝鑻ユ槸涓涓湁闄愮殑鏁板鹼紝鍒欑瓑寰呯浉搴旂殑
姣鏁板悗榪斿洖Event鐨勭姸鎬併?/p>
鍥犮傛墍璋撯滀簨浠垛濆氨鏄寚鈥滅姸鎬佺殑杞崲鈥濄傞氳繃Event鍙互鍦ㄧ嚎紼嬮棿浼犻掕繖縐嶁滅姸鎬佽漿鎹⑩濅俊鎭?/p>
浣滄湁鎵涓嶅悓錛屽畠鍙湁涓や釜鎿嶄綔錛欵nter鍜孡eave錛屽悓鏍峰彲浠ユ妸瀹冪殑涓や釜鐘舵佸綋浣淭rue鍜孎alse錛屽垎鍒〃紺虹幇鍦ㄦ槸鍚﹀浜庝復(fù)
鐣屽尯涓傝繖涓や釜鎿嶄綔涔熸槸鍘熻錛屾墍浠ュ畠鍙互鐢ㄤ簬鍦ㄥ綰跨▼搴旂敤涓繚鎶ゅ叡浜暟鎹紝闃叉璁塊棶鍐茬獊銆?/p>
鏈鍚庤皟鐢↙eave紱誨紑涓寸晫鍖恒傚畠鐨勪繚鎶ゅ師鐞嗘槸榪欐牱鐨勶細褰撲竴涓嚎紼嬭繘鍏ヤ復(fù)鐣屽尯鍚庯紝濡傛灉姝ゆ椂鍙︿竴涓嚎紼嬩篃瑕佽闂繖涓暟
鎹紝鍒欏畠浼氬湪璋冪敤Enter鏃訛紝鍙戠幇宸茬粡鏈夌嚎紼嬭繘鍏ヤ復(fù)鐣屽尯錛岀劧鍚庢綰跨▼灝變細琚寕璧鳳紝絳夊緟褰撳墠鍦ㄤ復(fù)鐣屽尯鐨勭嚎紼嬭皟鐢?br />Leave紱誨紑涓寸晫鍖猴紝褰撳彟涓涓嚎紼嬪畬鎴愭搷浣滐紝璋冪敤Leave紱誨紑鍚庯紝姝ょ嚎紼嬪氨浼氳鍞ら啋錛屽茍璁劇疆涓寸晫鍖烘爣蹇楋紝寮濮嬫搷浣滄暟
鎹紝榪欐牱灝遍槻姝簡璁塊棶鍐茬獊銆?/p>
Var
InterlockedCrit : TRTLCriticalSection;
Procedure InterlockedIncrement( var aValue : Integer );
Begin
聽聽聽 EnterCriticalSection( InterlockedCrit );
聽聽聽 Inc( aValue );
聽聽聽 LeaveCriticalSection( InterlockedCrit );
End;
1. 綰跨▼A榪涘叆涓寸晫鍖猴紙鍋囪鏁版嵁涓?錛?br />2. 綰跨▼B榪涘叆涓寸晫鍖猴紝鍥犱負(fù)A宸茬粡鍦ㄤ復(fù)鐣屽尯涓紝鎵浠琚寕璧?br />3. 綰跨▼A瀵規(guī)暟鎹姞涓錛堢幇鍦ㄦ槸4錛?br />4. 綰跨▼A紱誨紑涓寸晫鍖猴紝鍞ら啋綰跨▼B錛堢幇鍦ㄥ唴瀛樹腑鐨勬暟鎹槸4錛?br />5. 綰跨▼B琚敜閱掞紝瀵規(guī)暟鎹姞涓錛堢幇鍦ㄥ氨鏄?浜嗭級
6. 綰跨▼B紱誨紑涓寸晫鍖猴紝鐜板湪鐨勬暟鎹氨鏄紜殑浜嗐?/p>
鐣屽尯鎵嶆槸姝g‘鐨勫仛娉曪細
Try
// 鎿嶄綔涓寸晫鍖烘暟鎹?br />Finally
聽聽聽 LeaveCriticalSection
End;
TThread綾葷敤鍒扮殑涓涓叏灞Event錛歋yncEvent鍜屽叏灞CriticalSection錛歍headLock錛岄兘鏄湪
InitThreadSynchronization鍜孌oneThreadSynchronization涓繘琛屽垱寤哄拰閲婃斁鐨勶紝鑰屽畠浠垯鏄湪Classes鍗曞厓鐨?br />Initialization鍜孎inalization涓璋冪敤鐨勩?/p>
銆傛嵁鎴戞墍鐭ワ紝榪欐槸Delphi RTL涓畾涔夌殑鏈闀跨殑涓涓被鍚嶏紝榪樺ソ瀹冩湁涓涓煭鐨勫埆鍚嶏細TMREWSync銆傝嚦浜庡畠鐨勭敤澶勶紝鎴戞兂鍏?br />鐪嬪悕瀛楀氨鍙互鐭ラ亾浜嗭紝鎴戜篃灝變笉澶氳浜嗐?/p>
銆傚厛鏉ョ湅鐪婼ynchronize鐨勫疄鐜幫細
begin
聽聽聽 FSynchronize.FThread := Self;
聽聽聽 FSynchronize.FSynchronizeException := nil;
聽聽聽 FSynchronize.FMethod := Method;
聽聽聽 Synchronize(@FSynchronize);
end;
PSynchronizeRecord = ^TSynchronizeRecord;
TSynchronizeRecord = record
聽聽聽 FThread: TObject;
聽聽聽 FMethod: TThreadMethod;
聽聽聽 FSynchronizeException: TObject;
end;
涓被鏂規(guī)硶StaticSynchronize銆備笅闈㈡槸榪欎釜Synchronize鐨勪唬鐮侊細
var
聽聽聽 SyncProc: TSyncProc;
begin
聽聽聽 if GetCurrentThreadID = MainThreadID then
聽聽聽聽聽聽聽 ASyncRec.FMethod
聽聽聽 else begin
聽聽聽 SyncProc.Signal := CreateEvent(nil, True, False, nil);
聽聽聽 try
聽聽聽 EnterCriticalSection(ThreadLock);
聽聽聽 try
聽聽聽 if SyncList = nil then
聽聽聽聽聽聽聽 SyncList := TList.Create;
聽聽聽聽聽聽聽 SyncProc.SyncRec := ASyncRec;
聽聽聽聽聽聽聽 SyncList.Add(@SyncProc);
聽聽聽聽聽聽聽 SignalSyncEvent;
聽聽聽聽聽聽聽 if Assigned(WakeMainThread) then
聽聽聽聽聽聽聽聽聽聽聽 WakeMainThread(SyncProc.SyncRec.FThread);
聽聽聽聽聽聽聽 LeaveCriticalSection(ThreadLock);
聽聽聽聽聽聽聽 try
聽聽聽聽聽聽聽聽聽聽聽 WaitForSingleObject(SyncProc.Signal, INFINITE);
聽聽聽聽聽聽聽 finally
聽聽聽聽聽聽聽聽聽聽聽 EnterCriticalSection(ThreadLock);
聽聽聽聽聽聽聽 end;
聽聽聽聽聽聽聽 finally
聽聽聽聽聽聽聽聽聽聽聽 LeaveCriticalSection(ThreadLock);
聽聽聽聽聽聽聽 end;
聽聽聽聽聽聽聽 finally
聽聽聽聽聽聽聽聽聽聽聽 CloseHandle(SyncProc.Signal);
聽聽聽聽聽聽聽 end;
聽聽聽聽聽聽聽 if Assigned(ASyncRec.FSynchronizeException) then
聽聽聽聽聽聽聽聽聽聽聽 raise ASyncRec.FSynchronizeException;
聽聽聽 end;
end;
SyncRec: PSynchronizeRecord;
Signal: THandle;
end;
灞浜嬩歡銆傝繖閲屼箣鎵浠ヨ鐢ㄤ簨浠惰繘琛屽鐞嗭紝鏄洜涓篠ynchronize鏂規(guī)硶鏈川涓婃槸閫氳繃娑堟伅錛屽皢闇瑕佸悓姝ョ殑榪囩▼鏀懼埌涓葷嚎紼嬩腑
鎵ц錛屽鏋滃湪涓浜涙病鏈夋秷鎭驚鐜殑搴旂敤涓紙濡侰onsole鎴朌LL錛夋槸鏃犳硶浣跨敤鐨勶紝鎵浠ヨ浣跨敤榪欎釜浜嬩歡榪涜澶勭悊銆?br />鑰屽搷搴旇繖涓簨浠剁殑鏄疉pplication瀵硅薄錛屼笅闈袱涓柟娉曞垎鍒敤浜庤緗拰娓呯┖WakeMainThread浜嬩歡鐨勫搷搴旓紙鏉ヨ嚜Forms鍗曞厓錛夛細
begin
聽聽聽 Classes.WakeMainThread := WakeMainThread;
end;
begin
聽聽聽 Classes.WakeMainThread := nil;
end;
begin
聽聽聽 PostMessage(Handle, WM_NULL, 0, 0);
end;
procedure TApplication.WndProc(var Message: TMessage);
鈥?br />begin
聽聽聽 try
聽聽聽聽聽聽聽 鈥?br />聽聽聽聽聽聽聽 with Message do
聽聽聽聽聽聽聽 case Msg of
聽聽聽聽聽聽聽 鈥?br />聽聽聽聽聽聽聽 WM_NULL:
聽聽聽聽聽聽聽 CheckSynchronize;
聽聽聽聽聽聽聽 鈥?br />聽聽聽 except
聽聽聽聽聽聽聽 HandleException(Self);
聽聽聽 end;
end;
聽聽聽 WakeMainThread(SyncProc.SyncRec.FThread);
聽聽聽 WaitForSingleObject(SyncProc.Signal, INFINITE);
聽聽聽 finally
聽聽聽聽聽聽聽 LeaveCriticalSection(ThreadLock);
end;
浠g爜澶уぇ綆鍖栦簡錛屼絾鐪熺殑鍙互鍚楋紵
浜嬪疄涓婃槸涓嶈錛?/p>
寰呭埆鐨勭嚎紼婼etEvent鍚庢墠浼氳鍞ら啋銆傚鏋滄敼鎴愪笂闈㈤偅鏍風(fēng)殑浠g爜鐨勮瘽錛屽鏋滈偅涓猄etEvent鐨勭嚎紼嬩篃闇瑕佽繘鍏ヤ復(fù)鐣屽尯鐨勮瘽
錛屾閿侊紙Deadlock錛夊氨鍙戠敓浜嗭紙鍏充簬姝婚攣鐨勭悊璁猴紝璇瘋嚜琛屽弬鑰冩搷浣滅郴緇熷師鐞嗘柟闈㈢殑璧勬枡錛夈?br />姝婚攣鏄嚎紼嬪悓姝ヤ腑鏈闇瑕佹敞鎰忕殑鏂歸潰涔嬩竴錛?br />鏈鍚庨噴鏀懼紑濮嬫椂鍒涘緩鐨凟vent錛屽鏋滆鍚屾鐨勬柟娉曡繑鍥炲紓甯哥殑璇濓紝榪樹細鍦ㄨ繖閲屽啀嬈℃姏鍑哄紓甯搞?/p>
var
聽聽聽聽 SyncProc: PSyncProc;
聽聽聽聽 LocalSyncList: TList;
begin
聽聽聽聽 if GetCurrentThreadID <> MainThreadID then
聽聽聽聽聽聽聽聽聽 raise EThread.CreateResFmt(@SCheckSynchronizeError, [GetCurrentThreadID]);
聽聽聽聽 if Timeout > 0 then
聽聽聽聽聽聽聽聽聽 WaitForSyncEvent(Timeout)
聽聽聽聽 else
聽聽聽聽聽聽聽聽聽 ResetSyncEvent;
聽聽聽聽 LocalSyncList := nil;
聽聽聽聽 EnterCriticalSection(ThreadLock);
聽聽聽聽 try
聽聽聽聽聽聽聽聽聽 Integer(LocalSyncList) := InterlockedExchange(Integer(SyncList), Integer(LocalSyncList));
聽聽聽聽聽聽聽聽聽 try
聽聽聽聽聽聽聽聽聽聽聽聽聽聽 Result := (LocalSyncList <> nil) and (LocalSyncList.Count > 0);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽 if Result then begin
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 while LocalSyncList.Count > 0 do begin
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SyncProc := LocalSyncList[0];
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 LocalSyncList.Delete(0);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 LeaveCriticalSection(ThreadLock);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 try
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 try
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SyncProc.SyncRec.FMethod;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 except
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SyncProc.SyncRec.FSynchronizeException := AcquireExceptionObject;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 end;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 finally
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 EnterCriticalSection(ThreadLock);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 end;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 SetEvent(SyncProc.signal);
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 end;
聽聽聽聽聽聽聽聽聽聽聽聽聽聽 end;
聽聽聽聽聽聽聽聽聽 finally
聽聽聽聽聽聽聽聽聽聽聽聽聽聽 LocalSyncList.Free;
聽聽聽聽聽聽聽聽聽 end;
聽聽聽聽 finally
聽聽聽聽聽聽聽聽聽 LeaveCriticalSection(ThreadLock);
聽聽聽聽 end;
end;
Linux鐗堜笅鎵嶄細璋冪敤甯﹀弬鏁扮殑CheckSynchronize錛學(xué)indows鐗堜笅閮芥槸璋冪敤榛樿鍙傛暟0鐨凜heckSynchronize錛夈?br />鐜板湪鍙互鐪嬪嚭SyncList鐨勭敤閫斾簡錛氬畠鏄敤浜庤褰曟墍鏈夋湭琚墽琛岀殑鍚屾鏂規(guī)硶鐨勩傚洜涓轟富綰跨▼鍙湁涓涓紝鑰屽瓙綰跨▼鍙兘鏈?br />寰堝涓紝褰撳涓瓙綰跨▼鍚屾椂璋冪敤鍚屾鏂規(guī)硶鏃訛紝涓葷嚎紼嬪彲鑳戒竴鏃舵棤娉曞鐞嗭紝鎵浠ラ渶瑕佷竴涓垪琛ㄦ潵璁板綍瀹冧滑銆?br />鍦ㄨ繖閲岀敤涓涓眬閮ㄥ彉閲廘ocalSyncList鏉ヤ氦鎹yncList錛岃繖閲岀敤鐨勪篃鏄竴涓師璇細InterlockedExchange銆傚悓鏍鳳紝榪欓噷
涔熸槸鐢ㄤ復(fù)鐣屽尯灝嗗SyncList鐨勮闂繚鎶よ搗鏉ャ?br />鍙LocalSyncList涓嶄負(fù)絀猴紝鍒欓氳繃涓涓驚鐜潵渚濇澶勭悊绱Н鐨勬墍鏈夊悓姝ユ柟娉曡皟鐢ㄣ傛渶鍚庢妸澶勭悊瀹岀殑LocalSyncList閲?br />鏀炬帀錛岄鍑轟復(fù)鐣屽尯銆?/p>
錛堝師鍥犲綋鐒朵篃鏄負(fù)浜嗛槻姝㈡閿侊級銆?br />鎺ョ潃灝辨槸鐪熸鐨勮皟鐢ㄥ悓姝ユ柟娉曚簡銆?br />濡傛灉鍚屾鏂規(guī)硶涓嚭鐜板紓甯革紝灝嗚鎹曡幏鍚庡瓨鍏ュ悓姝ユ柟娉曟暟鎹褰曚腑銆?br />閲嶆柊榪涘叆涓寸晫鍖哄悗錛岃皟鐢⊿etEvent閫氱煡璋冪敤綰跨▼錛屽悓姝ユ柟娉曟墽琛屽畬鎴愪簡錛堣瑙佸墠闈ynchronize涓殑
WaitForSingleObject璋冪敤錛夈?br />鑷蟲錛屾暣涓猄ynchronize鐨勫疄鐜頒粙緇嶅畬鎴愩?/p>
var
聽聽聽 H: array[0..1] of THandle;
聽聽聽 WaitResult: Cardinal;
聽聽聽 Msg: TMsg;
begin
聽聽聽 H[0] := FHandle;
聽聽聽 if GetCurrentThreadID = MainThreadID then聽 begin
聽聽聽聽聽聽聽 WaitResult := 0;
聽聽聽聽聽聽聽 H[1] := SyncEvent;
聽聽聽聽聽聽聽 repeat
聽聽聽聽聽聽聽聽聽聽聽 { This prevents a potential deadlock if the background thread does a SendMessage to the foreground thread }
聽聽聽聽聽聽聽聽聽聽聽 if WaitResult = WAIT_OBJECT_0 + 2 then
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE);
聽聽聽聽聽聽聽聽聽聽聽 WaitResult := MsgWaitForMultipleObjects(2, H, False, 1000, QS_SENDMESSAGE);
聽聽聽聽聽聽聽聽聽聽聽 CheckThreadError(WaitResult <> WAIT_FAILED);
聽聽聽聽聽聽聽聽聽聽聽 if WaitResult = WAIT_OBJECT_0 + 1 then
聽聽聽聽聽聽聽聽聽聽聽聽聽聽聽 CheckSynchronize;
聽聽聽聽聽聽聽 until WaitResult = WAIT_OBJECT_0;
聽聽聽 end else
聽聽聽聽聽聽聽 WaitForSingleObject(H[0], INFINITE);
聽聽聽 CheckThreadError(GetExitCodeThread(H[0], Result));
end;
鍙傛暟錛岃瑙丮SDN涓叧浜庢API鐨勮鏄庯級銆傚彲浠ユ妸姝PI褰撲綔涓涓彲浠ュ悓鏃剁瓑寰呭涓狧andle鐨刉aitForSingleObject銆傚鏋?br />鏄疭yncEvent琚玈etEvent錛堣繑鍥濿AIT_OBJECT_0 + 1錛夛紝鍒欒皟鐢–heckSynchronize澶勭悊鍚屾鏂規(guī)硶銆?br />涓轟粈涔堝湪涓葷嚎紼嬩腑璋冪敤WaitFor蹇呴』鐢∕sgWaitForMultipleObjects錛岃屼笉鑳界敤WaitForSingleObject絳夊緟綰跨▼緇撴潫鍛紵
鍥犱負(fù)闃叉姝婚攣銆傜敱浜庡湪綰跨▼鍑芥暟Execute涓彲鑳借皟鐢⊿ynchronize澶勭悊鍚屾鏂規(guī)硶錛岃屽悓姝ユ柟娉曟槸鍦ㄤ富綰跨▼涓墽琛岀殑錛屽
鏋滅敤WaitForSingleObject絳夊緟鐨勮瘽錛屽垯涓葷嚎紼嬪湪榪欓噷琚寕璧鳳紝鍚屾鏂規(guī)硶鏃犳硶鎵ц錛屽鑷寸嚎紼嬩篃琚寕璧鳳紝浜庢槸鍙戠敓姝婚攣銆?br />鑰屾敼鐢╓aitForMultipleObjects鍒欐病鏈夎繖涓棶棰樸傞鍏堬紝瀹冪殑絎笁涓弬鏁頒負(fù)False錛岃〃紺哄彧瑕佺嚎紼婬andle鎴朣yncEvent
涓彧瑕佹湁涓涓猄ignaled鍗沖彲浣夸富綰跨▼琚敜閱掞紝鑷充簬鍔犱笂QS_SENDMESSAGE鏄洜涓篠ynchronize鏄氳繃娑堟伅浼犲埌涓葷嚎紼嬫潵鐨?br />錛屾墍浠ヨ繕瑕侀槻姝㈡秷鎭闃誨銆傝繖鏍鳳紝褰撶嚎紼嬩腑璋冪敤Synchronize鏃訛紝涓葷嚎紼嬪氨浼氳鍞ら啋騫跺鐞嗗悓姝ヨ皟鐢紝鍦ㄨ皟鐢ㄥ畬鎴愬悗
緇х畫榪涘叆鎸傝搗絳夊緟鐘舵侊紝鐩村埌綰跨▼緇撴潫銆?br />鑷蟲錛屽綰跨▼綾籘Thread鐨勫垎鏋愬彲浠ュ憡涓涓钀戒簡錛屽鍓嶉潰鐨勫垎鏋愪綔涓涓葷粨錛?br />1銆?綰跨▼綾葷殑綰跨▼蹇呴』鎸夋甯哥殑鏂瑰紡緇撴潫錛屽嵆Execute鎵ц緇撴潫錛屾墍浠ュ湪鍏朵腑鐨勪唬鐮佷腑蹇呴』鍦ㄩ傚綋鐨勫湴鏂瑰姞鍏ヨ凍澶熷
聽聽聽 鐨勫Terminated鏍囧織鐨勫垽鏂紝騫跺強鏃墮鍑恒傚鏋滃繀欏昏鈥滅珛鍗斥濋鍑猴紝鍒欎笉鑳戒嬌鐢ㄧ嚎紼嬬被錛岃岃鏀圭敤API鎴朢TL鍑芥暟銆?br />2銆?瀵瑰彲瑙哣CL鐨勮闂鏀懼湪Synchronize涓紝閫氳繃娑堟伅浼犻掑埌涓葷嚎紼嬩腑錛岀敱涓葷嚎紼嬪鐞嗐?br />3銆?綰跨▼鍏變韓鏁版嵁鐨勮闂簲璇ョ敤涓寸晫鍖鴻繘琛屼繚鎶わ紙褰撶劧鐢⊿ynchronize涔熻錛夈?br />4銆?綰跨▼閫氫俊鍙互閲囩敤Event榪涜錛堝綋鐒朵篃鍙互鐢⊿uspend/Resume錛夈?br />5銆?褰撳湪澶氱嚎紼嬪簲鐢ㄤ腑浣跨敤澶氱綰跨▼鍚屾鏂瑰紡鏃訛紝涓瀹氳灝忓績闃叉鍑虹幇姝婚攣銆?br />6銆?絳夊緟綰跨▼緇撴潫瑕佺敤WaitFor鏂規(guī)硶銆?/p>
//////////////////////////////////////////////
//---------鍙栧緱utf8瀛楃鐨勯暱搴?--------------//
//Str:String 婧愬瓧絎︿覆
//Result:Integer utf8瀛楃涓查暱搴?br>class function TPduPush.getUTF8Len(Str: string): Integer;
var
i: integer;
tmpChar: Pchar;
begin
tmpChar := pchar(str);
i := 0;
result := 0;
while i < length(tmpChar) do begin
if ord(tmpChar[i]) < $80 then begin
i := i + 1;
result := result + 1;
end else begin
i := i + 2;
result := result + 3;
end;
end;
end;
////////////////////////////////////////////////
//----------鍙栧緱瀛楃涓蹭腑鐨勫瓧絎︿釜鏁?-----------//
//str:String 婧愬瓧絎︿覆
//Result:Integer 瀛楃涓暟,鍏煎涓枃鍙屽瓧鑺?br>class function TPduPush.getAnsiLen(Str: string): integer;
var
i: integer;
tmpChar: Pchar;
begin
tmpChar := pchar(str);
i := 0;
result := 0;
while i < length(tmpChar) do begin
if ord(tmpChar[i]) < $80 then
i := i + 1
else
i := i + 2;
result := result + 1;
end;
end;
/////////////////////////////////////////////////
//---------鎴彇鎸囧畾闀垮害鐨剈tf8瀛楃涓?-----------//
//str:string 婧愬瓧絎︿覆
//count:Integer 鎸囧畾闀垮害 涓涓眽瀛楀崰涓変釜瀛楄妭,闀垮害鍙兘灝?涓嶈兘澶?br>//Result:string 鎴彇鍚庣殑utf8瀛楃涓?br>class function TPduPush.getUTF8String(Str: string; count: Integer): string;
var
i, j: integer;
tmpChar: Pchar;
begin
tmpChar := pchar(str);
i := 0;
j := 0;
result := '';
while i < length(tmpChar) do begin
if j >= count then break; //鑻辨枃杞爜鍚庝笉鑳借秴榪囨寚瀹氱殑浣嶆暟
if ord(tmpChar[i]) < $80 then begin
result := result + string(tmpChar[i]);
i := i + 1;
j := j + 1;
end else begin
if j + 2 >= count then break; //姹夊瓧杞爜鍚庝笉鑳借秴榪囨寚瀹氱殑浣嶆暟
result := result + string(tmpChar[i]) + string(tmpChar[i + 1]);
i := i + 2;
j := j + 3;
end;
end;
end;
灝介噺璁﹏ame鍜寀rl鐭偣錛岃繖鏍風(fēng)紪鐮佸悗鍙互鏀懼埌涓鏉$煭娑堟伅閲岄潰錛岃屼笉闇瑕佹妸涓涓緗媶鍒嗘垚澶氫釜鐭秷鎭綋銆傚ぇ鑷寸殑涓涓皝瑁呮槸鎶妜ml鏂囦歡杞垚wbxml錛岀劧鍚庡啀鍦ㄥ闈㈠皝瑁匴SP灞傦紝鏈澶栭潰鏄疻DP灞傘?/p>
WDP鐨勪竴鑸牸寮忔槸鈥?B0504C34FC002000304xxyy鈥濓紝鍏朵腑xx灝辨槸鏁翠釜鏁版嵁鍖呯殑鎬葷墖鏂暟鐩紝鑰寉y琛ㄧず褰撳墠鐗囨柇鏄鍑犱釜鐗囨柇銆備婦涓緥瀛愶紝涓涓畝鍗曠殑bookmark鍏ㄩ儴鏀懼湪涓涓猻ms涓繖鏍穢x錛?1錛寉y錛?1銆?br>涓嬮潰鏄瘡涓猙yte鐨勬剰鎬?
# 0B | User-Data-Header (UDHL) Length = 11 bytes
# 05 | UDH IE identifier: Port numbers
# 04 | UDH port number IE length
# C3 | Destination port (high)
# 4F | Destination port (low)
# C0 | Originating port (high)
# 02 | Originating port (low)
# 00 | UDH IE identifier: SAR
# 03 | UDH SAR IE length
# 04 | Datagram ref no.
#
# Two variable bytes, intentionally missing from WDP header, user must
# calculate and add at send time.
#
# xx | Total number of segments in datagram
# yy | Segment count
bookmark鐨刉SP灞傜殑鏍煎紡涓鑸槸"01062D1F2A6170706C69636174696F6E2F782D7761702D70726F762E62726F777365722D626F6F6B6D61726B730081EA"
姣忎釜byte鐨勫叿浣撴剰鎬濇槸錛?/p>
# 01 | Transaction ID /
# 06 | PDU type (push)
# xx | Header length (content type headers)
# 1F | Value length quote length greater than 30
# 2A | Value length (value name not used)
# xx | Mimetype encoded, variable bytes | application/x-wap-prov.browser-{bookmarks | settings}
# 00 | Null termination of content type string |
# 81 | Charset | Well known PARM. (short integer)
# EA | UTF-8 (using short integer)
鏈閲屽眰灝辨槸WBXML浜嗭紝棣栧厛蹇呴』鏈変釜xml鐨勫ご"01016A00"
# 01 | Version | WBXML 1.1
# 01 | Unknown public identifier |
# 6A | Charset | UTF-8
# 00 | String table length |
http://www.cnblogs.com/zhengyun_ustc/archive/2005/09/05/otawapbookmark.html
[SMS&WAP]瀹炰緥璁茶В鍒朵綔OTA鐭俊鏉ヨ嚜鍔ㄩ厤緗墜鏈篧AP涔︾[闄勬簮鐮乚
鎽樿:OTA錛屽嵆Over The Air錛屽浗鍐呯炕璇戜負(fù)絀轟腑涓嬭澆銆?
OTA鏍囧噯鐢辯埍绔嬩俊鍜岃鍩轟簹鍏卞悓鍒惰銆侽TA娑電洊浜嗚澶氳寖鍥達紝姣斿Kjava涓殑搴旂敤紼嬪簭涓嬭澆涔熸槸閫氳繃OTA銆傛垜浠繖綃囨枃绔犱富瑕佽鐨勬槸錛岄氳繃鐭俊鏂瑰紡絀轟腑涓嬭澆閰嶇疆淇℃伅錛屽弬鑰冪殑鏂囨。鏄疧TA_settings_general_7_0.pdf銆?
瑙勮寖涓畾涔変簡涓夌Setting錛?
? 嫻忚鍣ㄨ緗?
? 嫻忚鍣ㄧ殑涔︾璁劇疆
? SyncML璁劇疆
涔熷氨鏄錛屼綘閫氳繃鍙戦佺煭淇″彲浠ュ府鍔╃敤鎴鋒墜鏈洪厤緗繖涓夌璁劇疆銆?
鍘熷垯涓婏紝浣犲彧瑕佺湅浜哋TA_settings_general_7_0.pdf錛屽茍鍙傜収OTA_service_settings_example_v11.pdf錛屽氨鍙互杞繪澗鍦板埗浣滃嚭絎﹀悎瑙勮寖鐨凮TA鐭俊銆?
浣嗘槸錛屾湰鏂囨。鐨勭洰鐨勫氨鏄浣犵畝鍗曠矖鏆村湴鐩村涓婚錛岀湅瀹岃繖綃囨枃妗e悗錛屽氨浜嗚В浜哋TA鐭俊鐨勬蹇碉紝閫氳繃浠ヤ笅浠g爜錛?
OTAMessage
OTAMessage message = new OTAMessage();
txtOTAResult.Text = message.Get
鏈嶅姟鍣ㄧ浠g爜濡備笅:
鐢變簬姣旇緝綆鍗?鎵浠ヤ笉璐存敞閲婁簡,濡傛灉鏈変粈涔堜笉鎳俤鍦版柟,澶у瀵圭潃
unit Listener;
interface
uses
SysUtils, Controls, Forms, winsock, Classes, ComCtrls, StdCtrls;
const ASYNC_EVENT = $0400 + 1;
SO_CONDITIONAL_ACCEPT = $3002;
type
TCMSocketMessage = record //select 娑堟伅緇撴瀯
Msg: Cardinal; //緋葷粺娑堟伅
Socket: TSocket; //浜х敓娑堟伅鐨勬簮socket 鍙ユ焺
SelectEvent: Word; //select娑堟伅
SelectError: Word; //閿欒
Result: Longint;
end;
type
TMain = class(TForm)
SBar: TStatusBar;
Memo1: TMemo;
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
s: TSocket;
SClinent: TSocket;
procedure bindAddr;
procedure CMIncCount(var Msg: TCMSocketMessage); message ASYNC_EVENT;
procedure listenAddr;
{ Private declarations }
public
{ Public declarations }
end;
var
Main: TMain;
implementation
{$R *.dfm}
procedure TMain.FormDestroy(Sender: TObject);
begin
closeSocket(s);
WSACleanup();
end;
procedure TMain.FormCreate(Sender: TObject);
var
wsa: TWSaData;
flag: integer;
begin
SClinent := 0;
//SysUtils.BoolToStr()
flag := WSAStartup($0202, wsa); //鍔犺澆winsock
if flag <> 0 then begin
SBar.Panels[2].Text := format('閿欒鍙?%d', [WSAGetLastError()]);
SBar.Panels[1].Text := 'Winsock搴撳姞杞藉け璐?;
end;
bindAddr;
listenAddr;
end;
procedure TMain.bindAddr;
var
addr: TSockAddrIn;
flag: integer;
begin
s := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //鏈嶅姟鍣ㄧ鐨剆ocket
addr.sin_port := htons(45531);
addr.sin_family := AF_INET;
addr.sin_addr.S_addr := INADDR_ANY; //inet_addr(pchar(host));
flag := bind(s, addr, sizeof(addr));
if flag = SOCKET_ERROR then begin
SBar.Panels[2].Text := format('閿欒鍙?%d', [WSAGetLastError()]);
SBar.Panels[1].Text := 'IP緇戝畾閿欒';
end else begin
flag := WSAAsyncSelect(s, Handle, ASYNC_EVENT, FD_ACCEPT or FD_CONNECT or FD_CLOSE or FD_READ or FD_WRITE);
if flag = SOCKET_ERROR then begin
SBar.Panels[2].Text := format('閿欒鍙?%d', [WSAGetLastError()]);
SBar.Panels[1].Text := 'WSAAsyncSelect閿欒';
end;
end;
end;
procedure TMain.listenAddr;
var flag: integer;
begin
flag := listen(s, 10);
if flag = SOCKET_ERROR then begin
SBar.Panels[2].Text := format('閿欒鍙?%d', [WSAGetLastError()]);
SBar.Panels[1].Text := '鐩戝惉澶辮觸';
end;
end;
procedure TMain.CMIncCount(var Msg: TCMSocketMessage);
var
addr: TSockAddrIn;
len: integer;
SendBuf: array[1..1024] of AnsiChar;
recvBuf: array[1..1024] of AnsiChar;
str: string;
OldOpenType {, NewOpenType}: integer;
begin
len := 0;
str := '';
case Msg.SelectEvent of
FD_READ: begin
len := sizeof(recvBuf);
ioctlsocket(SClinent, FIONREAD, Longint(len));
fillchar(recvBuf, sizeof(recvBuf), 0);
recv(SClinent, recvBuf, sizeof(recvBuf), 0);
Memo1.Lines.Add(string(recvBuf));
Memo1.Lines.Add('read');
if Memo1.Lines.Count > 10 then
memo1.Clear;
sleep(10);
fillchar(SendBuf, sizeof(SendBuf), 0);
Strcopy(@SendBuf, pansichar('OK'));
Send(SClinent, sendbuf, sizeof(sendbuf), 0);
end;
FD_WRITE: begin
Memo1.Lines.Add('write');
end;
FD_ACCEPT: begin
len := sizeof(OldOpenType);
if getsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, PChar(@OldOpenType), len) = 0 then begin
try
len := sizeof(addr);
SClinent := accept(s, @addr, @len);
if SClinent = INVALID_SOCKET then begin
Memo1.Lines.Add('鏃犳晥鐨剆ocket:' + inttostr(SClinent));
end;
Memo1.Lines.Add('accept');
finally
len := sizeof(OldOpenType);
setsockopt(INVALID_SOCKET, SOL_SOCKET, SO_OPENTYPE, PChar(@OldOpenType), len);
end;
end;
WSAAsyncSelect(SClinent, handle, ASYNC_EVENT, $33);
end;
FD_CONNECT: begin
Memo1.Lines.Add('connect');
end;
FD_CLOSE: begin
Memo1.Lines.Add('close');
end;
end;
end;
end.
//鐢變簬鏈嶅姟鍣ㄧ娌℃湁緙撳瓨鏈哄埗,鎵浠ュ涓猚lient榪炴帴鐨勬椂鍊?絎簩涓猚lient鐨剆ocket浼氳鐩栧墠涓涓殑,澶у鐪嬫儏鍐墊敼鏀瑰氨琛屼簡,緗戠粶涓婂ぇ鎶婁唬鐮侀兘鏄敤鎺т歡鎴栬呭叾浠栧皝瑁呭ソd綾繪潵鍐檇,鎵浠ヨ祫鏂欓儊闂鋒浜?
瀹㈡埛绔唬鐮?
program Client;
{$APPTYPE CONSOLE}
uses
SysUtils,
windows,
winsock;
var
addr: TSockAddrIn;
wsa: TWSaData;
flag: integer;
s: TSocket;
Host: string;
Port: Word;
BufSend: array[1..1024] of Ansichar; //涓棿淇℃伅
BufRev: array[1..1024] of Ansichar;
i: Integer;
begin
{ TODO -oUser -cConsole Main : Insert code here }
Host := '127.0.0.1';
port := 45531;
flag := WSAStartup($0202, wsa); //鍔犺澆winsock
if flag <> 0 then begin
Writeln(format('閿欒鍙?%d', [WSAGetLastError()]));
Writeln('Winsock搴撳姞杞藉け璐?);
end else begin
Writeln('Winsock搴撳姞杞芥垚鍔?)
end;
//s := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //鏈嶅姟鍣ㄧ鐨剆ocket
s := socket(PF_INET, SOCK_STREAM, 0);
FillChar(addr, sizeof(addr), 0); //鍒濆鍖栧湴鍧絀洪棿
addr.sin_port := htons(port);
addr.sin_family := AF_INET;
addr.sin_addr.S_addr := {INADDR_ANY; } inet_addr(pchar(host));
if connect(s, addr, sizeof(addr)) = 0 then begin
Writeln('涓繪満:' + Host + ' 榪炴帴鎴愬姛')
end else begin
Writeln('涓繪満:' + Host + ' 榪炴帴澶辮觸');
end;
FillChar(BufSend, 1024, 0);
StrPCopy(@BufSend, '嫻嬭瘯淇℃伅鍖?);
for i := 0 to 100 do begin
Writeln(inttostr(s));
if Send(s, Bufsend, Length(BufSend), 0) <> SOCKET_ERROR then begin
Writeln('娑堟伅宸插彂閫?);
sleep(500);
FillChar(BufRev, 1024, 0);
//strcopy(bufsend,pansichar('a'))
if recv(s, BufRev, Length(BufSend), 0) <> SOCKET_ERROR then begin
writeln('鎺ユ敹鍒扮殑淇℃伅:' + trim(string(BufRev)));
end else begin
Writeln('鎺ユ敹娑堟伅澶辮觸!')
end;
end else begin
Writeln('娑堟伅鍙戦佸け璐?)
end;
end;
if closeSocket(s) = 0 then begin
Writeln('宸茬粡鍏抽棴socket')
end else begin
Writeln('鍏抽棴socket 鍑洪敊')
end;
WSACleanup();
Readln;
end.
鍏充簬delphi 鐨勫嚱鏁拌皟鐢ㄥ拰鍙傛暟浼犻掓柟寮忔繁鍏ョ爺絀?/p>
delphi 浠g爜濡備笅:
program Project1;
uses windows, SysUtils;
function a(d, dd: word; s, j, f: string): word;
begin
d := d - 1;
result := d + dd;
messagebox(0, pchar(inttostr(d) + s), pchar(inttostr(dd)), $0);
end;
var s: string;
begin
s := 'sssssssssss';
{ asm
mov dx,$11
mov ax,$33
call a;
end; }
a($33, $11, 'sssss', s, s);
end.
姹囩紪浠g爜:
00407CA8 . 447C4000 DD Project1.00407C44
00407CAC > $ 55 PUSH EBP //淇濆瓨鏍堥《
00407CAD . 8BEC MOV EBP,ESP //鍒濆鍖栧爢鏍?br>00407CAF . 83C4 F0 ADD ESP,-10 //寮杈?0涓瓧鑺傜殑鏍?br>00407CB2 . B8 6C7C4000 MOV EAX,Project1.00407C6C
00407CB7 . E8 34C7FFFF CALL Project1.004043F0
00407CBC . 33C0 XOR EAX,EAX //EAX娓?
00407CBE . 55 PUSH EBP //淇濆瓨鏍堥《
00407CBF . 68 037D4000 PUSH Project1.00407D03 //淇濆瓨榪斿洖鍦板潃
00407CC4 . 64:FF30 PUSH DWORD PTR FS:[EAX] //
00407CC7 . 64:8920 MOV DWORD PTR FS:[EAX],ESP //
00407CCA . B8 48984000 MOV EAX,Project1.00409848
00407CCF . BA 187D4000 MOV EDX,Project1.00407D18 ; ASCII "sssssssssss" //鍒濆鍖栧眬閮ㄥ彉閲?br>00407CD4 . E8 2FB9FFFF CALL Project1.00403608
00407CD9 . 68 2C7D4000 PUSH Project1.00407D2C ; ASCII "jjjjjjjjjj"
00407CDE . 68 407D4000 PUSH Project1.00407D40 ; ASCII "ffffffffffff"
00407CE3 . B9 587D4000 MOV ECX,Project1.00407D58 ; ASCII "sssss"
00407CE8 . 66:BA 1100 MOV DX,11
00407CEC . 66:B8 3300 MOV AX,33
00407CF0 . E8 9BFEFFFF CALL Project1.00407B90 //璋冪敤鍑芥暟
00407CF5 . 33C0 XOR EAX,EAX
00407CF7 . 5A POP EDX
00407CF8 . 59 POP ECX
00407CF9 . 59 POP ECX
00407CFA . 64:8910 MOV DWORD PTR FS:[EAX],EDX
00407CFD . 68 0A7D4000 PUSH Project1.00407D0A
00407D02 > C3 RETN ; RET used as a jump to 00407D0A
00407D03 .^E9 D4B2FFFF JMP Project1.00402FDC
00407D08 .^EB F8 JMP SHORT Project1.00407D02
00407D0A E8 DB E8
00407D0B B5 DB B5
00407D0C B7 DB B7
00407D0D FF DB FF
00407D0E FF DB FF
00407D0F 00 DB 00
00407D10 . FFFFFFFF DD FFFFFFFF
00407D14 . 0B000000 DD 0000000B
00407D18 . 73 73 73 73 73>ASCII "sssssssssss",0
00407D24 . FFFFFFFF DD FFFFFFFF
00407D28 . 0A000000 DD 0000000A
00407D2C . 6A 6A 6A 6A 6A>ASCII "jjjjjjjjjj",0
00407D37 00 DB 00
00407D38 . FFFFFFFF DD FFFFFFFF
00407D3C . 0C000000 DD 0000000C
00407D40 . 66 66 66 66 66>ASCII "ffffffffffff",0
00407D4D 00 DB 00
00407D4E 00 DB 00
00407D4F 00 DB 00
00407D50 . FFFFFFFF DD FFFFFFFF
00407D54 . 05000000 DD 00000005
00407D58 . 73 73 73 73 73>ASCII "sssss",0
function a(d, dd: word; s, j, f: string): word;
鍑芥暟鐨勪唬鐮?
00407B90 /$ 55 PUSH EBP
00407B91 |. 8BEC MOV EBP,ESP
00407B93 |. 6A 00 PUSH 0
00407B95 |. 6A 00 PUSH 0
00407B97 |. 6A 00 PUSH 0
00407B99 |. 53 PUSH EBX
00407B9A |. 56 PUSH ESI
00407B9B |. 57 PUSH EDI
00407B9C |. 894D FC MOV DWORD PTR SS:[EBP-4],ECX
00407B9F |. 8BF2 MOV ESI,EDX
00407BA1 |. 8BD8 MOV EBX,EAX
00407BA3 |. 8B45 FC MOV EAX,DWORD PTR SS:[EBP-4]
00407BA6 |. E8 49BDFFFF CALL Project1.004038F4
00407BAB |. 8B45 0C MOV EAX,DWORD PTR SS:[EBP+C]
00407BAE |. E8 41BDFFFF CALL Project1.004038F4
00407BB3 |. 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
00407BB6 |. E8 39BDFFFF CALL Project1.004038F4
00407BBB |. 33C0 XOR EAX,EAX
00407BBD |. 55 PUSH EBP
00407BBE |. 68 317C4000 PUSH Project1.00407C31
00407BC3 |. 64:FF30 PUSH DWORD PTR FS:[EAX]
00407BC6 |. 64:8920 MOV DWORD PTR FS:[EAX],ESP
00407BC9 |. 4B DEC EBX
00407BCA |. 8D3C1E LEA EDI,DWORD PTR DS:[ESI+EBX]
00407BCD |. 6A 00 PUSH 0
00407BCF |. 8D55 F8 LEA EDX,DWORD PTR SS:[EBP-8]
00407BD2 |. 0FB7C6 MOVZX EAX,SI
00407BD5 |. E8 5AD6FFFF CALL Project1.00405234
00407BDA |. 8B45 F8 MOV EAX,DWORD PTR SS:[EBP-8]
00407BDD |. E8 22BDFFFF CALL Project1.00403904
00407BE2 |. 50 PUSH EAX
00407BE3 |. 8D55 F4 LEA EDX,DWORD PTR SS:[EBP-C]
00407BE6 |. 0FB7C3 MOVZX EAX,BX
00407BE9 |. E8 46D6FFFF CALL Project1.00405234
00407BEE |. 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
00407BF1 |. 8B55 FC MOV EDX,DWORD PTR SS:[EBP-4]
00407BF4 |. E8 33BCFFFF CALL Project1.0040382C
00407BF9 |. 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C]
00407BFC |. E8 03BDFFFF CALL Project1.00403904
00407C01 |. 50 PUSH EAX ; |Text
00407C02 |. 6A 00 PUSH 0 ; |hOwner = NULL
00407C04 |. E8 23C9FFFF CALL <JMP.&user32.MessageBoxA> ; \MessageBoxA //榪欓噷stdcall鏂瑰紡璋冪敤messagebox
00407C09 |. 33C0 XOR EAX,EAX
00407C0B |. 5A POP EDX
00407C0C |. 59 POP ECX
00407C0D |. 59 POP ECX
00407C0E |. 64:8910 MOV DWORD PTR FS:[EAX],EDX
00407C11 |. 68 387C4000 PUSH Project1.00407C38
00407C16 |> 8D45 F4 LEA EAX,DWORD PTR SS:[EBP-C]
00407C19 |. BA 03000000 MOV EDX,3
00407C1E |. E8 B5B9FFFF CALL Project1.004035D8
00407C23 |. 8D45 08 LEA EAX,DWORD PTR SS:[EBP+8]
00407C26 |. BA 02000000 MOV EDX,2
00407C2B |. E8 A8B9FFFF CALL Project1.004035D8
00407C30 \. C3 RETN
debug registers :
/** 涓葷▼搴?鍖呭惈鍑犱釜杞爜鐨勫嚱鏁?/font>
* 浣滆?鍒樻槅
* 鏈鍚庝慨鏀規(guī)棩鏈? 2004-11-18
* 浠ヤ笂浠g爜鍏嶈垂,鑻ョ洿鎺ュ紩鐢ㄤ竴涓嬩唬鐮佽鍛婄煡,騫朵繚鐣欐娉ㄩ噴
* 浣滀負(fù)涓鍚嶇▼搴忓憳搴旇鏈夋渶鍩烘湰鐨勮亴涓氶亾寰?/
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
TFormMain = class(TForm)
Panel1: TPanel;
Memo1: TMemo;
ComboBox1: TComboBox;
Button1: TButton;
Memo2: TMemo;
procedure Button1Click(Sender: TObject);
private
function StrToUTF8(str: WideString): string;
function StrToASC(Str: string): string;
function GB2Unicode(Str: WideString): string; overload;
//function GB2Unicode(Str: string): string; overload;
function U2GB(Str: string): string;
function UTF8ToStr(const str: UTF8String): string;
function HexToInt(const Str: string): integer;
function HexIndex(const c: Char): Integer;
{ Private declarations }
public
{ Public declarations }
end;
var
FormMain: TFormMain;
implementation
{$R *.dfm}
{ TFormMain }
function TFormMain.StrToASC(Str: string): string;
var
TmpStr: string;
TmpPchar: Pchar;
i: integer;
begin
result := '';
TmpStr := '';
TmpPchar := pchar(Str);
for i := 0 to length(TmpPchar) - 1 do
TmpStr := TmpStr + format('%2.2x', [ord(TmpPchar[i])]);
result := TmpStr;
end;
function TFormMain.StrToUTF8(str: WideString): string;
var
s: pchar;
i: integer;
tmp: string;
begin
tmp := '';
result := '';
s := pchar(Utf8encode(str));
for i := 0 to strlen(s) do begin
tmp := tmp + format('%2.2x', [ord(s[i])]);
end;
result := tmp;
end;
function TFormMain.UTF8ToStr(const str: UTF8String): string;
var
s: pchar;
i: integer;
tmp: string;
begin
tmp := '';
result := '';
s := PChar(str);
i := 0;
while i < length(s) do begin
tmp := tmp + chr(HexToInt(s[i] + s[i + 1]));
inc(i, 2);
end;
result := Utf8Decode(tmp);
end;
function TFormMain.GB2Unicode(Str: WideString): string;
var
i: Integer;
begin
Result := '';
for i := 1 to Length(Str) do
Result := Result + Format('%4.4x', [ord(Str[i])]);
end;
procedure TFormMain.Button1Click(Sender: TObject);
begin
case ComboBox1.ItemIndex of
0: memo2.Lines.Add(GB2Unicode(memo1.Lines.Text));
1: memo2.Lines.Add(StrToUTF8(memo1.Lines.Text));
2: memo2.Lines.Add(UTF8ToStr(memo1.Lines.Text));
3: memo2.Lines.Add(U2GB(StringReplace(memo1.Lines.Text, '\u', '', [rfReplaceAll])));
4: memo2.Lines.Add(StrToASC(memo1.Lines.Text));
end;
end;
function TFormMain.HexToInt(const Str: string): integer;
var p: pchar;
begin
result := -1;
if length(str) > 2 then exit;
p := pchar(str);
if (HexIndex(p[0]) <> -1) and (HexIndex(p[1]) <> -1) then
result := HexIndex(p[0]) * $10 + HexIndex(p[1]);
end;
function TFormMain.HexIndex(const c: Char): Integer;
const Digits: array[0..15] of Char = ('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F');
var i: integer;
begin
result := -1;
if (not (UpCase(c) in ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'])) then
exit;
for i := 0 to high(digits) do
if Digits[i] = UpCase(c) then begin
result := i;
break;
end;
end;
function TFormMain.U2GB(Str: string): string;
var s: pchar;
i: integer;
tmp: string;
begin
tmp := '';
result := '';
s := PChar(str);
i := 0;
while i < length(s) do begin
tmp := tmp + chr(HexToInt(s[i + 2] + s[i + 3])) + chr(HexToInt(s[i] + s[i + 1]));//unicode杞崲鏃?楂樹綆浣嶄簰鎹?br> inc(i, 4);
end;
result := widechartostring(pWideChar(tmp + #0#0#0#0));
end;
end.
/** 紼嬪簭鐨勬牳蹇?涓涓猵ost綰跨▼,鐢ㄤ簬鎻愪氦xml鏁版嵁鍖?/font>
* 浣滆?鍒樻槅
* 鏈鍚庝慨鏀規(guī)棩鏈? 2004-9-23
* 浠ヤ笂浠g爜鍏嶈垂,鑻ョ洿鎺ュ紩鐢ㄤ竴涓嬩唬鐮佽鍛婄煡,騫朵繚鐣欐娉ㄩ噴
* 浣滀負(fù)涓鍚嶇▼搴忓憳搴旇鏈夋渶鍩烘湰鐨勮亴涓氶亾寰?/
unit HTTPGetThread;
interface
uses classes, SysUtils, wininet, windows;
type
TOnProgressEvent = procedure(TotalSize, Readed: Integer) of object;
THTTPGetThread = class(TThread)
private
FTAcceptTypes: string; //鎺ユ敹鏂囦歡綾誨瀷 *.*
FTAgent: string; //嫻忚鍣ㄥ悕 Nokia6610/1.0 (5.52) Profile/MIDP-1.0 Configuration/CLDC-1.02
FTURL: string; // url
FTFileName: string; //鏂囦歡鍚?br> FTStringResult: AnsiString;
FTUserName: string; //鐢ㄦ埛鍚?br> FTPassword: string; //瀵嗙爜
FTPostQuery: string; //鏂規(guī)硶鍚?post鎴栬単et
FTReferer: string;
FTBinaryData: Boolean;
FTUseCache: Boolean; //鏄惁浠庣紦瀛樿鏁版嵁
FTMimeType: string; //Mime綾誨瀷
FTResult: Boolean;
FTFileSize: Integer;
FTToFile: Boolean; //鏄惁鏂囦歡
BytesToRead, BytesReaded: LongWord;
FTProgress: TOnProgressEvent;
procedure ParseURL(URL: string; var HostName, FileName: string; var portNO: integer); //鍙栧緱url鐨勪富鏈哄悕鍜屾枃浠跺悕
procedure UpdateProgress;
protected
procedure Execute; override;
public
procedure setResult(FResult: boolean);
function getResult(): boolean;
function getFileName(): string;
function getToFile(): boolean;
function getFileSize(): integer;
function getStringResult(): AnsiString;
constructor Create(aAcceptTypes, aMimeType, aAgent, aURL, aFileName,
aUserName, aPassword, aPostQuery, aReferer: string; aBinaryData,
aUseCache: Boolean; aProgress: TOnProgressEvent; aToFile: Boolean);
end;
implementation
{ THTTPGetThread }
constructor
THTTPGetThread.Create(aAcceptTypes, aMimeType, aAgent, aURL, aFileName,
aUserName, aPassword, aPostQuery, aReferer: string; aBinaryData,
aUseCache: Boolean; aProgress: TOnProgressEvent; aToFile: Boolean);
begin
FreeOnTerminate := True;
inherited Create(True);
FTAcceptTypes := aAcceptTypes;
FTAgent := aAgent;
FTURL := aURL;
FTFileName := aFileName;
FTUserName := aUserName;
FTPassword := aPassword;
//FTPostQuery := aPostQuery;
FTPostQuery := StringReplace(aPostQuery, #13#10, '', [rfReplaceAll]);
FTReferer := aReferer;
FTProgress := aProgress;
FTBinaryData := aBinaryData;
FTUseCache := aUseCache;
FTMimeType := aMimeType;
FTToFile := aToFile;
Resume;
end;
procedure THTTPGetThread.Execute;
var
hSession: hInternet; //鍥炶瘽鍙ユ焺
hConnect: hInternet; //榪炴帴鍙ユ焺
hRequest: hInternet; //璇鋒眰鍙ユ焺
Host_Name: string; //涓繪満鍚?br> File_Name: string; //鏂囦歡鍚?br> port_no: integer;
RequestMethod: PChar;
InternetFlag: longWord;
AcceptType: PAnsiChar;
dwBufLen, dwIndex: longword;
Buf: Pointer; //緙撳啿鍖?br> f: file;
Data: array[0..$400] of Char;
TempStr: AnsiString;
mime_Head: string;
procedure CloseHandles;
begin
InternetCloseHandle(hRequest);
InternetCloseHandle(hConnect);
InternetCloseHandle(hSession);
end;
begin
inherited;
buf := nil;
try
try
ParseURL(FTURL, Host_Name, File_Name, port_no);
if Terminated then begin
FTResult := False;
Exit;
end;
//寤虹珛浼氳瘽
hSession := InternetOpen(pchar(FTAgent), //lpszCallerName鎸囧畾姝e湪浣跨敤緗戠粶鍑芥暟鐨勫簲鐢ㄧ▼搴?br> INTERNET_OPEN_TYPE_PRECONFIG, //鍙傛暟dwAccessType鎸囧畾璁塊棶綾誨瀷
nil, //鏈嶅姟鍣ㄥ悕錛坙pszProxyName錛夈?accesstype涓篏ATEWAY_PROXY_INTERNET_ACCESS鍜孋ERN_PROXY_ACCESS鏃?br> nil, //NProxyPort鍙傛暟鐢ㄥ湪CERN_PROXY_INTERNET_ACCESS涓敤鏉ユ寚瀹氫嬌鐢ㄧ殑绔彛鏁般備嬌鐢↖NTERNET_INVALID_PORT_NUMBER鐩稿綋浜庢彁渚涘嵈鐪佺殑绔彛鏁般?br> 0); //璁劇疆棰濆鐨勯夋嫨銆備綘鍙互浣跨敤INTERNET_FLAG_ASYNC鏍囧織鍘繪寚紺轟嬌鐢ㄨ繑鍥炲彞鍙ユ焺鐨勫皢鏉ョ殑Internet鍑芥暟灝嗕負(fù)鍥炶皟鍑芥暟鍙戦佺姸鎬佷俊鎭紝浣跨敤InternetSetStatusCallback榪涜姝ら」璁劇疆
//寤虹珛榪炴帴
hConnect := InternetConnect(hSession, //浼氳瘽鍙ユ焺
PChar(Host_Name), //鎸囧悜鍖呭惈Internet鏈嶅姟鍣ㄧ殑涓繪満鍚嶇О錛堝http://www.mit.edu錛夋垨IP鍦板潃錛堝202.102.13.141錛夌殑瀛楃涓?br> port_no, //INTERNET_DEFAULT_HTTP_PORT, //鏄皢瑕佽繛緇撳埌鐨凾CP/IP鐨勭鍙e彿
PChar(FTUserName), //鐢ㄦ埛鍚?br> PChar(FTPassword), //瀵嗙爜
INTERNET_SERVICE_HTTP, //鍗忚
0, // 鍙夋爣璁幫紝璁劇疆涓篒NTERNET_FLAG_SECURE錛岃〃紺轟嬌鐢⊿SL/PCT鍗忚瀹屾垚浜嬪姟
0); //搴旂敤紼嬪簭瀹氫箟鐨勫鹼紝鐢ㄦ潵涓鴻繑鍥炵殑鍙ユ焺鏍囪瘑搴旂敤紼嬪簭璁懼鍦哄
if FTPostQuery = '' then RequestMethod := 'GET'
else RequestMethod := 'POST';
if FTUseCache then InternetFlag := 0
else InternetFlag := INTERNET_FLAG_RELOAD;
AcceptType := PChar('Accept: ' + FTAcceptTypes);
//寤虹珛涓涓猦ttp璇鋒眰鍙ユ焺
hRequest := HttpOpenRequest(hConnect, //InternetConnect榪斿洖鐨凥TTP浼氳瘽鍙ユ焺
RequestMethod, //鎸囧悜鍦ㄧ敵璇蜂腑浣跨敤鐨?鍔ㄨ瘝"鐨勫瓧絎︿覆錛屽鏋滆緗負(fù)NULL錛屽垯浣跨敤"GET"
PChar(File_Name), //鎸囧悜鍖呭惈鍔ㄨ瘝鐨勭洰鏍囧璞″悕縐扮殑瀛楃涓詫紝閫氬父鏄枃浠跺悕縐般佸彲鎵ц妯″潡鎴栨悳绱㈣鏄庣
'HTTP/1.0', //鎸囧悜鍖呭惈HTTP鐗堟湰鐨勫瓧絎︿覆錛屽鏋滀負(fù)NULL錛屽垯榛樿涓?HTTP/1.0"錛?br> PChar(FTReferer), //鎸囧悜鍖呭惈鏂囨。鍦板潃錛圲RL錛夌殑瀛楃涓詫紝鐢寵鐨刄RL蹇呴』鏄粠璇ユ枃妗h幏鍙栫殑
@AcceptType, //鎸囧悜瀹㈡埛鎺ユ敹鐨勫唴瀹圭殑綾誨瀷
InternetFlag,
0);
mime_Head := 'Content-Type: ' + FTMimeType;
if FTPostQuery = '' then
FTResult := HttpSendRequest(hRequest, nil, 0, nil, 0)
else
//鍙戦佷竴涓寚瀹氳姹傚埌httpserver
FTResult := HttpSendRequest(hRequest,
pchar(mime_Head), //mime 澶?br> length(mime_Head), //澶撮暱搴?br> PChar(FTPostQuery), //闄勫姞鏁版嵁緙撳啿鍖猴紝鍙負(fù)絀?br> strlen(PChar(FTPostQuery))); //闄勫姞鏁版嵁緙撳啿鍖洪暱搴?/font>
if Terminated then
begin
//CloseHandles;
FTResult := False;
Exit;
end;
dwIndex := 0;
dwBufLen := 1024;
GetMem(Buf, dwBufLen);
//鎺ユ敹header淇℃伅鍜屼竴涓猦ttp璇鋒眰
FTResult := HttpQueryInfo(hRequest,
HTTP_QUERY_CONTENT_LENGTH,
Buf, //鎸囧悜涓涓帴鏀惰姹備俊鎭殑緙撳啿鍖虹殑鎸囬拡
dwBufLen, //HttpQueryInfo鍐呭鐨勫ぇ灝?br> dwIndex); //璇誨彇鐨勫瓧鑺傛暟
if Terminated then begin
FTResult := False;
Exit;
end;
if FTResult or not FTBinaryData then begin //濡傛灉璇鋒眰
if FTResult then
FTFileSize := StrToInt(StrPas(Buf));
BytesReaded := 0;
if FTToFile then begin
AssignFile(f, FTFileName);
Rewrite(f, 1);
end else FTStringResult := '';
while True do begin
if Terminated then begin
FTResult := False;
Exit;
end;
if not InternetReadFile(hRequest,
@Data, //鏁版嵁鍐呭
SizeOf(Data), //澶у皬
BytesToRead) //璇誨彇鐨勫瓧鑺傛暟
then Break
else
if BytesToRead = 0 then Break
else begin
if FTToFile then
BlockWrite(f, Data, BytesToRead) //灝嗚鍑虹殑鏁版嵁鍐欏叆鏂囦歡
else begin
TempStr := Data;
SetLength(TempStr, BytesToRead);
FTStringResult := FTStringResult + TempStr;
end;
inc(BytesReaded, BytesToRead);
if Assigned(FTProgress) then //鎵ц鍥炶皟鍑芥暟
Synchronize(UpdateProgress);
end;
end;
if FTToFile then
FTResult := FTFileSize = Integer(BytesReaded)
else begin
// SetLength(FTStringResult, BytesReaded);
FTResult := BytesReaded <> 0;
end;
end;
except
end;
finally
if FTToFile then CloseFile(f);
if assigned(Buf) then FreeMem(Buf);
CloseHandles;
end;
end;
function THTTPGetThread.getFileName: string;
begin
result := FTFileName;
end;
function THTTPGetThread.getFileSize: integer;
begin
result := FTFileSize;
end;
function THTTPGetThread.getResult: boolean;
begin
result := FTResult;
end;
function THTTPGetThread.getStringResult: AnsiString;
begin
result := FTStringResult;
end;
function THTTPGetThread.getToFile: boolean;
begin
result := FTToFile;
end;
procedure THTTPGetThread.ParseURL(URL: string; var HostName, FileName: string; var portNO: integer);
var
i: Integer;
begin
if Pos('http://', LowerCase(URL)) <> 0 then
Delete(URL, 1, 7);
i := Pos('/', URL);
HostName := Copy(URL, 1, i);
FileName := Copy(URL, i, Length(URL) - i + 1);
i := pos(':', hostName);
if i <> 0 then begin
portNO := strtoint(copy(hostName, i + 1, length(hostName) - i - 1));
hostName := copy(hostName, 1, i - 1);
end else portNO := 80;
if (Length(HostName) > 0) and (HostName[Length(HostName)] = '/') then SetLength(HostName, Length(HostName) - 1);
end;
procedure THTTPGetThread.setResult(FResult: boolean);
begin
FTResult := FResult;
end;
procedure THTTPGetThread.UpdateProgress;
begin
FTProgress(FTFileSize, BytesReaded);
end;
end.
/** 涓昏鐢ㄦ潵鍋氱嚎紼嬪拰鐣岄潰鐨勪氦浜?/font>
* 浣滆?鍒樻槅
* 鏈鍚庝慨鏀規(guī)棩鏈? 2004-9-23
* 浠ヤ笂浠g爜鍏嶈垂,鑻ョ洿鎺ュ紩鐢ㄤ竴涓嬩唬鐮佽鍛婄煡,騫朵繚鐣欐娉ㄩ噴
* 浣滀負(fù)涓鍚嶇▼搴忓憳搴旇鏈夋渶鍩烘湰鐨勮亴涓氶亾寰?/
unit MyHttpGet;
interface
uses HTTPGetThread, windows;
type
TOnDoneFileEvent = procedure(FileName: string; FileSize: Integer) of object;
TOnDoneStringEvent = procedure(Result: AnsiString) of object;
THttpGet = class
private
F_URL: string; //鐩爣url
F_GetURLThread: THTTPGetThread; //鍙栨暟鎹殑綰跨▼
F_Accept_Types: string;
F_Agent: string;
F_Binary_Data: Boolean;
F_Use_Cache: Boolean; //鏄惁璇葷紦瀛?br> F_File_Name: string;
F_User_Name: string; //鐢ㄦ埛鍚?br> F_Password: string; //瀵嗙爜
F_PostQuery: string; //鏂規(guī)硶鍚?br> F_Referer: string;
F_Mime_Type: string;
F_Wait_Thread: Boolean;
FResult: Boolean;
FProgress: TOnProgressEvent;
FDoneFile: TOnDoneFileEvent;
FDoneString: TOnDoneStringEvent;
procedure ThreadDone(Sender: TObject);
public
constructor Create();
destructor Destroy(); override;
procedure getFile();
procedure GetString();
procedure Abort();
published
property WaitThread: Boolean read F_Wait_Thread write F_Wait_Thread;
property AcceptTypes: string read F_Accept_Types write F_Accept_Types;
property Agent: string read F_Agent write F_Agent;
property BinaryData: Boolean read F_Binary_Data write F_Binary_Data;
property URL: string read F_URL write F_URL;
property UseCache: Boolean read F_Use_Cache write F_Use_Cache;
property FileName: string read F_File_Name write F_File_Name;
property UserName: string read F_User_Name write F_User_Name;
property Password: string read F_Password write F_Password;
property PostQuery: string read F_PostQuery write F_PostQuery;
property Referer: string read F_Referer write F_Referer;
property MimeType: string read F_Mime_Type write F_Mime_Type;
property OnDoneFile: TOnDoneFileEvent read FDoneFile write FDoneFile;
property OnDoneString: TOnDoneStringEvent read FDoneString write FDoneString;
end;
implementation
{ THttpGet }
procedure THttpGet.Abort;
begin
if Assigned(F_GetURLThread) then
begin
F_GetURLThread.Terminate;
F_GetURLThread.setResult(false);
end;
end;
constructor THttpGet.Create;
begin
F_Accept_Types := '*/*';
F_Agent := 'Nokia6610/1.0 (5.52) Profile/MIDP-1.0 Configuration/CLDC-1.02';
end;
destructor THttpGet.Destroy;
begin
end;
procedure THttpGet.getFile;
var
Msg: TMsg;
begin
if not Assigned(F_GetURLThread) then
begin
F_GetURLThread := THTTPGetThread.Create(F_Accept_Types,F_Mime_Type,
F_Agent, F_URL, F_File_Name, F_User_Name, F_Password, F_PostQuery,
F_Referer, F_Binary_Data, F_Use_Cache, FProgress, true);
F_GetURLThread.OnTerminate := ThreadDone;
if F_Wait_Thread then
while Assigned(F_GetURLThread) do
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do
begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
end;
procedure THttpGet.GetString;
var
Msg: TMsg;
begin
if not Assigned(F_GetURLThread) then
begin
F_GetURLThread :=
THTTPGetThread.Create(F_Accept_Types,F_Mime_Type,F_Agent, F_URL,
F_File_Name, F_User_Name, F_Password, F_PostQuery, F_Referer,
F_Binary_Data, F_Use_Cache, FProgress, False);
F_GetURLThread.OnTerminate := ThreadDone;
if F_Wait_Thread then
while Assigned(F_GetURLThread) do
while PeekMessage(Msg, 0, 0, 0, PM_REMOVE) do begin
TranslateMessage(Msg);
DispatchMessage(Msg);
end;
end
end;
procedure THttpGet.ThreadDone(Sender: TObject);
begin
FResult := F_GetURLThread.getResult;
if FResult then
if F_GetURLThread.getToFile then begin
if Assigned(FDoneFile) then FDoneFile(F_GetURLThread.getFileName, F_GetURLThread.getFileSize)
end else
if Assigned(FDoneString) then FDoneString(F_GetURLThread.getStringResult);
//end else if Assigned(FError) then FError(Self);
F_GetURLThread := nil;
end;
end.
/** 紼嬪簭涓葷晫闈?/font>
* 浣滆?鍒樻槅
* 鏈鍚庝慨鏀規(guī)棩鏈? 2004-9-23
* 浠ヤ笂浠g爜鍏嶈垂,鑻ョ洿鎺ュ紩鐢ㄤ竴涓嬩唬鐮佽鍛婄煡,騫朵繚鐣欐娉ㄩ噴
* 浣滀負(fù)涓鍚嶇▼搴忓憳搴旇鏈夋渶鍩烘湰鐨勮亴涓氶亾寰?/
unit MainForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, MyHttpGet;
type
TMain = class(TForm)
Panel1: TPanel;
Edit1: TEdit;
Label1: TLabel;
Panel2: TPanel;
Panel3: TPanel;
GroupBox1: TGroupBox;
MeSend: TMemo;
GroupBox2: TGroupBox;
MeReceive: TMemo;
Button1: TButton;
CbSave: TCheckBox;
Edit2: TEdit;
Label2: TLabel;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure onGetString(Result: AnsiString);
procedure onGetFile(FileName: string; FileSize: Integer);
public
{ Public declarations }
end;
var
Main: TMain;
implementation
{$R *.dfm}
procedure TMain.Button1Click(Sender: TObject);
var hg: THttpGet;
strs: TStrings;
i: Integer;
begin
hg := nil;
strs := nil;
try
strs := TStringList.Create;
hg := THttpGet.Create;
hg.WaitThread := false;
hg.AcceptTypes := '*.*';
hg.Agent := 'Nokia6610/1.0 (5.52) Profile/MIDP-1.0 Configuration/CLDC-1.02';
hg.BinaryData := false;
hg.URL := 'Http://' + Edit1.Text;
hg.UseCache := false;
hg.FileName := 'provison.xml';
hg.UserName := '';
hg.Password := '';
for i := 0 to MeSend.Lines.Count - 1 do
strs.Add(trim(MeSend.Lines[i]));
hg.PostQuery := strs.Text;
hg.Referer := 'Http://' + Edit1.Text; //text/plain
hg.MimeType := Edit2.Text;
hg.OnDoneString := onGetString;
hg.OnDoneFile := onGetFile;
hg.GetString;
finally
strs.Free;
hg.Free;
end;
end;
procedure TMain.onGetFile(FileName: string; FileSize: Integer);
begin
end;
procedure TMain.onGetString(Result: AnsiString);
begin
MeReceive.Lines.Text := Result;
end;
end.
鎴戝彂瑾?瑕佽榪欎簺鎶婃妧鏈嫿鍦ㄦ墜閲岄タ姝?
闈?鑳藉啓涓妸杞歡浜嗕笉璧峰晩,
榪欎釜鍐欏畬浜嗕互鍚?鐓ф棫寮婧?鐓ф棫涓嶇敤絎笁鏂規(guī)帶浠舵垨class
濡傛灉浣犲紩鐢ㄦ垨鑰呬慨鏀逛互涓嬩唬鐮?璇蜂笉瑕佸幓鎺夋敞閲?榪欎釜娑夊強鍒頒竴涓▼搴忓憳鐨勮亴涓氶亾寰烽棶棰?/p>
杞澆璇鋒敞鏄?/p>
/** 鏈唬鐮佷負(fù)鏃ュ織class
* 浣滆?鍒樻槅
* 鏈鍚庝慨鏀規(guī)棩鏈? 2004-9-23
* 浠ヤ笂浠g爜鍏嶈垂,鑻ョ洿鎺ュ紩鐢ㄤ竴涓嬩唬鐮佽鍛婄煡,騫朵繚鐣欐娉ㄩ噴
* 浣滀負(fù)涓鍚嶇▼搴忓憳搴旇鏈夋渶鍩烘湰鐨勮亴涓氶亾寰?/
unit pushLog;
interface
uses classes, sysutils, windows;
var
ThreadLock: TRTLCriticalSection; //涓寸晫鍖?/p>
const PathDelim = '\';
DriveDelim = ':';
type
Tlog = class
private
//logfile: file;
fileName: string;
function dirExist(const DirName: string): boolean;
function getDirName(const fileName: string): string;
function LastDelimiter(const Delimiters, S: string): Integer;
procedure createLogDir();
public
constructor Create(const filename: string);
destructor Destroy(); override;
procedure addLog(p: Pchar);
end;
implementation
{ Tlog }
procedure Tlog.addLog(p: Pchar);
var log_Line: pchar;
log_len: integer;
handle: Thandle;
des_Len: longword;
begin
EnterCriticalSection(ThreadLock);
log_Line := nil;
handle := $0;
des_Len := $0;
try
createLogDir;
log_len := strlen(p);
getmem(log_Line, log_len);
strcopy(log_Line, p);
handle := createfile(
pchar(fileName), //鏂囦歡鍚?br> GENERIC_READ or GENERIC_WRITE, //鏈熸湜瀛樺彇妯″紡 閫氱敤璇誨啓
FILE_SHARE_READ or FILE_SHARE_WRITE, //鍏變韓妯″紡
nil, //瀹氫箟鏂囦歡瀹夊叏鐗規(guī)х殑鎸囬拡錛堝墠鎻愶細鎿嶄綔緋葷粺鏀寔錛夈?br> OPEN_ALWAYS, //鎵撳紑鍜屽垱寤烘枃浠舵柟寮忋?br> FILE_ATTRIBUTE_NORMAL or FILE_FLAG_RANDOM_ACCESS, //瑕佹墦寮鏂囦歡鐨勬爣蹇楀拰灞炴э紙濡傦細闅愯棌錛岀郴緇熺瓑錛夈?br> 0); //妯℃澘鏂囦歡鍙ユ焺
if handle <> INVALID_HANDLE_VALUE then begin
SetFilePointer(handle, 0, nil, FILE_END);
WriteFile(handle, log_Line^, log_len, des_Len, nil);
end;
finally
CloseHandle(handle);
freeMem(log_Line);
LeaveCriticalSection(ThreadLock);
end;
end;
constructor Tlog.Create(const filename: string);
begin
self.fileName := filename;
end;
procedure Tlog.createLogDir;
var dir_Name: string;
begin
dir_Name := getDirName(fileName) + '\log';
if not DirExist(dir_Name) then begin //媯嫻嬫棩蹇楃洰褰曟槸鍚﹀瓨鍦?br> mkdir(dir_Name);
end;
end;
destructor Tlog.Destroy;
begin
inherited;
end;
function Tlog.DirExist(const DirName: string): boolean;
var
Handle: THandle;
FindData: TWin32FindData;
begin
result := false;
Handle := FindFirstFile(PChar(DirName), FindData);
if Handle <> INVALID_HANDLE_VALUE then begin
FindClose(Handle);
if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = $10 then begin
result := true;
end;
end;
end;
function Tlog.getDirName(const fileName: string): string;
var
I: Integer;
begin
I := LastDelimiter(':\', Filename);
if (I > 1) and (FileName[I] = PathDelim) and (((FileName[I - 1]
<> PathDelim) and (FileName[I - 1] <> DriveDelim)) or
(ByteType(FileName, I - 1) = mbTrailByte)) then
Dec(I);
while (ByteType(FileName, I - 1) = mbTrailByte) and (I > 0) do
Dec(I);
Result := Copy(FileName, 1, I);
end;
function Tlog.LastDelimiter(const Delimiters, S: string): Integer;
var
P: PChar;
begin
Result := Length(S);
P := PChar(Delimiters);
while Result > 0 do
begin
if (S[Result] <> #0) and (StrScan(P, S[Result]) <> nil) then // 媯嫻嬫渶鍚庝竴涓瓧絎︽槸鍚︿負(fù) '\'鎴栬?:'
if (ByteType(S, Result) = mbTrailByte) then
Dec(Result)
else
Exit;
Dec(Result);
end;
end;
initialization
InitializeCriticalSection(ThreadLock);
finalization
DeleteCriticalSection(ThreadLock);
end.
璋冪敤鏂規(guī)硶
procedure TMain.Button1Click(Sender: TObject);
var
log: Tlog;
begin
log := Tlog.Create(ExtractFileDir(Application.Exename) + '\' + 'aa.log');
log.addLog(pchar('濂界殑' + #13#10));
log.addLog(pchar('aaaaaaaaaaaaaaaaaaaa' + #13#10));
log.Free;
end;
鏂囨湰鏂囦歡鏄敱鑻ュ共琛岀粍鎴愮殑錛岃嫢騫蹭釜瀛楃涓茬粍鎴愪竴琛岋紝涓琛岀殑緇撳熬鐢卞洖杞︽崲琛岀琛ㄧず銆傚鏋滃鏂囨湰鏂囦歡榪涜鎿嶄綔錛屽垯棣栧厛搴旈氳繃璋冪敤AssignFile榪? 紼嬪緩绔嬫枃浠跺彉閲忎笌澶栭儴鏂囦歡鐨勮仈緋伙紝騫朵笖浣跨敤Reset鎴朢eWrite鎴朅ppend鏂規(guī)硶鎵撳紑銆傜敱浜庢枃鏈枃浠舵槸浠ヨ涓哄崟浣嶈繘琛岃鍐欐搷浣滅殑錛屽茍涓旀瘡涓琛岀殑闀? 搴︿笉涓瀹氱浉鍚岋紝鎵浠ヤ笉鑳借綆楀嚭鎸囧畾琛屽湪鏂囦歡涓殑鍑嗙‘浣嶇疆錛屽洜姝ゅ浜庢枃浠跺彧鑳介『搴忕殑璇誨啓銆傝瀵規(guī)枃浠惰繘琛岃鍐欐搷浣滐紝蹇呴』鐩稿簲鐨勫鏂囦歡榪涜浠ヨ鎴栧啓鐨勬柟寮忔墦寮錛? 涔熷氨鏄涓涓枃鏈枃浠跺彧鑳藉崟鐙繘琛岃鎴栧啓鐨勬搷浣滐紝鑰屼笉鑳藉悓鏃惰繘琛屻?/p>
1銆?浠ユ坊鍔犳柟寮忔墦寮鏂囦歡(Append)
閫氳繃璋冪敤鍑芥暟Append鍙墦寮涓涓凡緇忓瓨鍦ㄧ殑鏂囦歡浠ヤ究鍦ㄦ枃浠舵湯灝炬坊鍔犳枃鏈傚鏋滃湪鏂囦歡鏈鍚庣殑128涓瓧鑺傚潡涓紝瀛樺湪瀛楃銆坈trl銆?銆坺銆夛紙ASCII26錛夛紝閭d箞鏂囦歡灝嗗湪瀛楄妭澶勬彃鍏ワ紝騫朵笖瑕嗙洊璇ュ瓧絎︺?/p>
Append榪囩▼鐨勫0鏄庡涓嬶細
procedure Append(var F:text);
鍏? 涓璅鏄竴涓換鎰忔枃浠剁被鍨嬬殑鍙橀噺錛屽茍涓斿繀欏誨悓鐢ˋssignFile鍑芥暟鎵撳紑鐨勫閮ㄦ枃浠剁浉鑱旂郴錛屽鏋滄寚瀹氱殑鏂囦歡涓嶅瓨鍦紝鍒欎細浜х敓閿欒錛屽鏋滄寚瀹氱殑鏂囦歡宸茬粡鎵? 寮錛屽垯鍏堝叧闂啀閲嶆柊鎵撳紑銆傚綋鍓嶆枃浠剁殑浣嶇疆璁劇疆鍦ㄦ枃浠舵湯灝俱傚鏋滃垎閰嶇粰F鐨勬槸涓涓┖鍚嶅瓧錛屽垯鍦ㄨ皟鐢ˋppend鍑芥暟鍚庯紝鏂囦歡鍙橀噺錛團錛夊皢鍚屽皢鍚屾爣鍑嗚緭鍑烘枃浠? 寤虹珛鑱旂郴銆?/p>
2 銆佹枃鏈枃浠剁殑璇誨彇鍜屽啓鍏?/p>
鏂囨湰鏂囦歡閫氳繃璋冪敤榪囩▼Reset鍚庝互鍙鏂瑰紡鎵撳紑鍚庯紝灝卞彲浠ヤ嬌鐢≧ead鎴朢eadln榪囩▼鏉ヨ鍙栨枃浠舵暟鎹簡銆傛枃鏈枃浠墮氳繃璋冪敤Write鎴朩riteln榪囩▼鏉ユ墦寮涓鏂囦歡鍚庡氨鍙互浣跨敤鎴栬繃紼嬫潵鍐欏叆鏁版嵁銆?/p>
(1) 鐢≧ead榪囩▼璇誨彇鏁版嵁
閫氳繃璋冪敤Read榪囩▼鍙互浠庢枃鏈枃浠朵腑璇誨彇鎴栨暟瀛椼傚叾澹版槑濡備笅錛?br>Procedure Read([var F:text;]v1 [,v2,鈥?vn,]);
鍏? 涓璅鏄竴涓枃浠跺彉閲忥紝v1 ,v2,鈥?vn鐢ㄤ簬瀛樺偍璇誨彇鐨勬暟鎹紝鍏跺繀欏諱負(fù)鐩稿悓鐨勭被鍨嬨傚綋v1 ,v2,鈥?vn瀹氫箟涓哄瓧絎︿覆鍨嬫垨瀛楃鍨嬪彉閲忔椂錛屽垯Read榪囩▼灝嗘寜鐓у畾涔夌殑闀垮害璇誨彇瀛楃銆傚綋v1 ,v2,鈥?vn瀹氫箟涓烘暣鏁版垨瀹炴暟鍙橀噺鏃訛紝鍒橰ead榪囩▼灝嗕互絀烘牸浣滀負(fù)鍒嗛殧絎︼紝濡傛灉鍦ㄦ暟瀛椾腑鍑虹幇閫楀彿銆佸垎鍙鋒垨鍏朵粬瀛楃灝嗕駭鐢熷紓甯搞?/p>
(2) 鐢≧eadln榪囩▼璇誨彇鏁版嵁
閫氳繃璋冪敤Readln 榪囩▼鍙互浠庢枃鏈枃浠朵腑璇誨彇瀛楃涓層佸瓧絎︽垨鏁板瓧錛岀洿鍒頒竴琛岀粨鏉熴傚叾澹版槑濡備笅錛?br>Procedure readln([var F:text;]v1 [,v2 ,鈥);
鍏朵腑F鏄竴涓枃浠跺彉閲忥紝v1 ,v2,鈥?vn鐢ㄤ簬瀛樺偍璇誨彇鐨勬暟鎹?/p>
(3) 鐢╓rite榪囩▼鍐欏叆鏁版嵁
閫氳繃璋冪敤Write榪囩▼鍙互鍚戞枃浠朵腑鍐欏叆鏁版嵁銆傚叾澹版槑濡備笅錛?br>Procedure Write([var F:text;]p1[,p2,鈥);
鍏朵腑F鏄竴涓枃浠跺彉閲忥紝p1 ,p2,鈥?pn鐢ㄤ簬瀛樺偍鍐欏叆鐨勬暟鎹?/p>
(4) Writeln鐢ㄨ繃紼嬪啓鍏ユ暟鎹?/p>
閫氳繃璋冪敤Writeln榪囩▼鍙互鍚戞枃浠朵腑鍐欏叆涓琛屾暟鎹紝騫跺湪緇撳熬澶勮緭鍏ュ洖杞︾銆傚0鏄庡涓嬶細
Procedure Writeln([var F:text;]P1[,P2,鈥):
3銆?鏂囦歡鐨勫熀鏈搷浣?/p>
瀵規(guī)枃鏈枃浠惰繘琛屾搷浣滅殑鍩烘湰鍑芥暟涓庤繃紼嬭琛細
鏂規(guī)硶 璇存槑
Procedure AssignPrn(var F:text); 寤虹珛鏂囨湰鏂囦歡鍚屾墦鍗版満鐨勮仈緋?nbsp;
Function Eoln(var F:text):Boolean; 媯嫻嬫枃浠舵寚閽堟槸鍚︽寚鍚戣灝?nbsp;
Procedure Flush(var F:text); 娓呯┖浠ヨ緭鍑烘柟寮忥紙ReWite鎴朅ppend錛夋墦寮鐨勬枃浠剁紦鍐插尯錛屼互紜繚鍐欏叆鐨勬枃浠跺瓧絎﹂兘琚啓鍏ュ閮ㄦ枃浠?nbsp;
Function SeekEof(var F:text): boolean; 榪斿洖鏂囦歡灝劇姸鎬?nbsp;
Function SeekEoln(var F:text):boolean; 榪斿洖鏂囦歡琛屽熬鐘舵?nbsp;
Procedure SetTextBuf(var F :text;var buf [;size:integer]); 璁劇疆鏂囦歡緙撳啿鍖?/p>