[Delphi]多線程編程(16)多線程同步之WaitableTimer(等待定時器對象)[續(xù)二]_第1頁
[Delphi]多線程編程(16)多線程同步之WaitableTimer(等待定時器對象)[續(xù)二]_第2頁
[Delphi]多線程編程(16)多線程同步之WaitableTimer(等待定時器對象)[續(xù)二]_第3頁
[Delphi]多線程編程(16)多線程同步之WaitableTimer(等待定時器對象)[續(xù)二]_第4頁
[Delphi]多線程編程(16)多線程同步之WaitableTimer(等待定時器對象)[續(xù)二]_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

1、想過沒有?WaitableTimer是在定時等待,前面例子中的WaitForSingleObject等待函數(shù)也在等待,這就雙重等待了,這不好,太浪費資源.其實作為同步工具,前面的幾種方法(事件、信號、臨界區(qū))基本夠用了;WaitableTimer的作用并不是為了重復前面的功能,它的主要功用類似TTimer類;譬如每隔多長時間執(zhí)行一段代碼、或在指定的時間去執(zhí)行一段代碼.既然有了方便的TTimer,何必再使用WaitableTimer呢?因為WaitableTimer比TTimer精確的多,它的間隔時間可以精確到毫秒、它的指定時間甚至是精確到0.1毫秒;而TTimer驅(qū)動的WM_TIMER消息,是

2、消息隊列中優(yōu)先級最低的,也就是再同一時刻WM_TIMER消息總是被最后處理.還有重要的一點WaitableTimer可以跨線程、跨進程使用.繼續(xù)探討一個重要的點:很多時候為了讓線程不沖突,線程也在等待,既然有等待,那WaitableTimer非常精確的定時又有什么價值呢?對這個問題的思考,可以讓我們很好地理解APC函數(shù).SetWaitableTimer有個回調(diào)函數(shù)(其實是個過程),Windows要求它的格式是:procedureTimerAPCProc(lpArgToCompletionRoutine:Pointer;dwTimerLowValue:DWORD;dwTimerHighValue

3、:DWORD);stdcall;函數(shù)名中有APC的字樣,指示這是個APC函數(shù)(盡管這個名稱無所謂,這是官方命名),那什么是APC函數(shù)?APC(AsyncroneusProcedureCall):異步過程調(diào)用.原來每個線程除了有單獨的消息隊列,還有一個APC隊列(等待執(zhí)行的APC函數(shù));如果線程發(fā)現(xiàn)APC隊列中有情況,馬上會跳過去執(zhí)行,執(zhí)行完畢后才回來接著處理消息隊列.說起來麻煩,使用的時候只按上面格式傳入函數(shù)指針就行;不過能進入APC隊列的回調(diào)函數(shù)和其他回調(diào)函數(shù)還有一個很大的不同:SetWaitableTimer按格式調(diào)用APC函數(shù)后,需要在當前線程見到一個等待,此APC函數(shù)才可以進入隊列.這

4、好像很費解,例說一下:APC隊列有那么高的優(yōu)先級,因為對資源的優(yōu)先使用會對其他消息有很大的影響,肯定不能隨便進入,這是不是像生活中的貴賓席或貴賓通道?也就是說,要進入APC隊列只有SetWaitableTimer的調(diào)用還不夠,還要通過等待函數(shù)介紹一下.WaitForSingleObje(嗎?不是,它不夠級別;下面是Windows認可的、可以介紹APC入列的等待函數(shù):SleepEx();WaitForSingleObjectEx();WaitForMultipleObjectsEx();MsgWaitForMultipleObjectsEx();SignalObjectAndWait();為什么

5、是用等待函數(shù)來把關(guān)?因為上面幾個等待函數(shù)也可以等待是否有APC函數(shù)想入列.上面給出的幾個等待函數(shù),就SleepEx的參數(shù)最少,先用它吧:1functionSleepEx(dwMilliseconds:DWORD;毫秒數(shù)bAlertable:BOOL布爾值):DWORD;stdcall;/第一個參數(shù)和Sleep的那個參數(shù)是一樣的,是線程等待(或叫掛起)的時間,時間一到不管后面參數(shù)如何都會返回./第二個參數(shù)如果是False,SleepEx將不會關(guān)照APC函數(shù)是否入列;/若是True,只要有APC函數(shù)申請,SleepEx不管第一個參數(shù)如何都會把APC推入隊列并隨APC函數(shù)一起返回./注意:SetWa

6、itableTimer和SleepEx必須在同一個線程才可以.本例效果圖:代碼文件:unitUnit1;interfaceusesWindows,Messages,SysUtils,Variants,Classes,Graphics,Controls,Forms,Dialogs,ExtCtrls,StdCtrls;typeTForm1=class(TForm)Button1:TButton;procedureButton1Click(Sender:TObject);procedureFormDestroy(Sender:TObject);end;varForm1:TForm1;implemen

7、tation$R*.dfmvarhTimer:THandle;APC函數(shù)(過程),函數(shù)名和參數(shù)名可以不同,格式必須如此procedureTimerAPCProc(lpArgToCompletionRoutine:Pointer;dwTimerLowValue:DWORD;dwTimerHighValue:DWORD);stdcall;beginForm1.Text:=IntToStr(StrToIntDef(Form1.Text,0)+1);標題+1end;procedureTForm1.Button1Click(Sender:TObject);varDueTime:Int64;beginhT

8、imer:=CreateWaitableTimer(nil,True,nil);DueTime:=0;ifSetWaitableTimer(hTimer,DueTime,0,TimerAPCProc,nil,False)thenbeginSleepEx(INFINITE,True);INFINITE表示一直等end;TObject);end;procedureTForm1.FormDestroy(Sender:beginCloseHandle(hTimer);end;end.窗體文件:objectForm1:TForm1Left=0Top=0Caption=Form1ClientHeight=

9、113ClientWidth=203Color=clBtnFaceFont.Charset=DEFAULT_CHARSETFont.Color=clWindowTextFont.Height=-11Font.Name=TahomaFont.Style=OldCreateOrder=FalsePixelsPerInch=96TextHeight=13objectButton1:TButtonLeft=64Top=48Width=75Height=25Caption=Button1TabOrder=0OnClick=Button1Clickendend在上面例子中,每點一次鼠標,那個回調(diào)函數(shù)才執(zhí)行

10、一次;作為定時器,如果想讓它每秒執(zhí)行一次怎么弄?但每一次執(zhí)行那個APC函數(shù),都得有SleepEx(當然不止它)給送進去,那這樣得反復調(diào)用SleepEx才可以.怎么調(diào)用,用循環(huán)嗎?別說網(wǎng)上能找到的例子我沒見到不用循環(huán)的(太笨了),就在那個APC函數(shù)里調(diào)用不就完了.當然這時一般要設時間間隔的,下面我們將設間隔為1000(1秒).但接著問題又來了,譬如把代碼修改成:varhTimer:THandle;procedureTimerAPCProc(lpArgToCompletionRoutine:Pointer;dwTimerLowValue:DWORD;dwTimerHighValue:DWORD);

11、stdcall;beginForm1.Text:=IntToStr(StrToIntDef(Form1.Text,0)+1);SleepEx(INFINITE,True);這里再次調(diào)用SleepExend;procedureTForm1.Button1Click(Sender:TObject);varDueTime:Int64;beginhTimer:=CreateWaitableTimer(nil,True,nil);DueTime:=0;下面的參數(shù)1000表示間隔1秒ifSetWaitableTimer(hTimer,DueTime,1000,TimerAPCProc,nil,False)

12、thenbeginSleepEx(INFINITE,True);end;end;procedureTForm1.FormDestroy(Sender:TObject);beginCloseHandle(hTimer);end;任務能完成,但窗體死了.怎么辦?嘿,現(xiàn)在學的不是多線程嗎?面例子中,同時使用了CancelWaitableTimer來取消定時器,很好理解;效果圖:代碼文件:unitUnit1;interfaceend;end;end;,Graphics,Pointer;0)+1);usesWindows,Messages,SysUtils,Variants,ClassesControl

13、s,Forms,Dialogs,ExtCtrls,StdCtrls;typeTForm1=class(TForm)Button1:TButton;Button2:TButton;procedureButton1Click(Sender:TObject);procedureButton2Click(Sender:TObject);procedureFormDestroy(Sender:TObject);end;varForm1:TForm1;implementation$R*.dfmvarhTimer:THandle;APC函數(shù)procedureTimerAPCProc(lpArgToCompl

14、etionRoutine:dwTimerLowValue:DWORD;dwTimerHighValue:DWORD);stdcall;beginForm1.Text:=IntToStr(StrToIntDef(Form1.Text,SleepEx(INFINITE,True);線程入口函數(shù)functionMyThreadFun(p:Pointer):Integer;stdcall;varDueTime:Int64;beginDueTime:=0;SetWaitableTimer必須與SleepEx在同一線程ifSetWaitableTimer(hTimer,DueTime,1000,Timer

15、APCProc,nil,False)thenbeginSleepEx(INFINITE,True);end;Result:=0;end;procedureTForm1.Button1Click(Sender:TObject);varID:DWORD;begin建立WaitableTimer對象ifhTimer=0thenhTimer:=CreateWaitableTimer(nil,True,nil);CreateThread(nil,0,MyThreadFun,nil,0,ID);建立線程end;procedureTForm1.Button2Click(Sender:TObject);beg

16、inCancelWaitableTimer(hTimer);取消定時器endend;procedureTForm1.FormDestroy(Sender:TObject);beginCloseHandle(hTimer);end;end.窗體文件:objectForm1:TForm1Left=0Top=0Caption=Form1ClientHeight=113ClientWidth=203Color=clBtnFaceFont.Charset=DEFAULT_CHARSETFont.Color=clWindowTextFont.Height=-11Font.Name=TahomaFont.Style=OldCreateOrder=FalsePixelsPerInch=96TextHeight=13objectButton1:TButtonLeft=55Top=

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論