版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 HYPERLINK /sifenkesi/archive/2011/06/01/2065673.html 精确获取时间(QueryPerformanceCounter)LARGE_INTEGER tima,timb;QueryPerformanceCounter(&tima);在 Windows Server 2003 和 WindowsXP 中使用 QueryPerformanceCounter 函数的程序可能执行不当QueryPerformanceCounter 來精確計算執行時間QueryPerformanceCounter 來精確計算執行時間/ 這個程式展示了如何使用QueryPer
2、formanceCounter 來精確計算執行時間/代码LARGGE_IINTEEGERRm_liPPerffFreeq=0;/获获取每秒秒多少CCPUPerrforrmannceTicckQueeryPPerfformmancceFrrequuenccy(&m_lliPeerfFFreqq);LARRGE_INTTEGEERmm_liiPerrfSttartt=00;QueeryPPerfformmancceCoountter(&m_liPPerffStaart);forr(inntii=0;i1000;i+)cooutieendll;LARRGE_INTTEGEERlliPeerfNNow
3、=0;/计算CPPU运行行到现在在的时间间QueeryPPerfformmancceCoountter(&liiPerrfNoow);intttiime=(liiPerrfNoow.QQuaddParrt-m_liPPerffStaart.QuaadPaart)*10000)/m_lliPeerfFFreqq.QuuadPPartt);chaarbbufffer1000;sprrinttf(bbufffer,執行時間間%ddmiilliiseccondd,timme);couutbuffferreendll;QuerryPeerfoormaanceeCouunteer()这个函函数返回回高精确
4、确度性能能计数器器的值,它可以以以微妙妙为单位位计时.但是QuueryyPerrforrmannceCCounnterr()确确切的精精确计时时的最小小单位是是与系统统有关的的,所以,必须要要查询系系统以得得到QuueryyPerrforrmannceCCounnterr()返返回的嘀嘀哒声的的频率.QueeryPPerfformmancceFrrequuenccy()提供了了这个频频率值,返回每秒秒嘀哒声声的个数数.计算确确切的时时间是从从第一次次调用QQuerryPeerfoormaanceeCouunteer()开始的的假设得得到的LLARGGE_IINTEEGERR为nSttarttC
5、ouunteer,过过一段时时间后再再次调用用该函数数结束的的,设得到到nSttopCCounnterr.两者者之差除除以QuueryyPerrforrmannceFFreqquenncy()的频频率就是是开始到到结束之之间的秒秒数.由于计计时函数数本身要要耗费很很少的时时间,要减去去一个很很少的时时间开销销.但一般般都把这这个开销销忽略.公式如如下: nSttopCCounnterr-nSStarrtCoountterElaapseedTiime=- - oveerheeadfreequeencyydooublle ttimee=(nnStoopCoountter.QuaadPaart-nS
6、ttarttCouunteer.QQuaddParrt)/freequeencyy.QuuadPPartt这两个函函数是VVC提供供的仅供供Winndowws 995及其其后续版版本使用用的精确确时间函函数,并并要求计计算机从从硬件上上支持精精确定时时器。QQuerryPeerfoormaanceeFreequeencyy()函函数和QQuerryPeerfoormaanceeCouunteer()函数的的原型如如下: BOOOL QueeryPPerfformmancceFrrequuenccy(LLARGGE_IINTEEGERR llpFrrequuenccy); BOOOL Queer
7、yPPerfformmancceCoountter(LARRGE_INTTEGEER lpCCounnt);数据据类型AARGEE_INNTEGGER既既可以是是一个88字节长长的整型型数,也也可以是是两个44字节长长的整型型数的联联合结构构,其具体体用法根根据编译译器是否否支持664位而而定。该该类型的的定义如如下:typeedeff unnionn _LLARGGE_IINTEEGERR struuct DWWORDD LoowPaart ;/ 4字字节整型型数 LOONG HiighPPartt;/ 4字字节整型型数 ; LOONGLLONGG QuuadPPartt ;/ 88字节整整
8、型数LARRGE_INTTEGEER ;在进进行定时时之前,先调用用QueeryPPerfformmancceFrrequuenccy()函数获获得机器器内部定定时器的的时钟频频率,然后在在需要严严格定时时的事件件发生之之前和发发生之后后分别调调用QuueryyPerrforrmannceCCounnterr()函函数,利利用两次次获得的的计数之之差及时时钟频率率,计算算出事件件经历的精精确时间间。下列列代码实实现1mms的精精确定时时:LARRGE_INTTEGEERllitmmp;LONNGLOONGQPaart11,QPPartt2;douubleedffMinnus,dffFreeq,
9、dfTTim;QueeryPPerfformmancceFrrequuenccy(&littmp);dfFFreqq=(dooublle)llitmmp.QQuaddParrt;/获获得计数数器的时时钟频率率QueeryPPerfformmancceCoountter(&liitmpp);QPaart11=littmp.QuaadPaart;/获得初初始值doQueeryPPerfformmancceCoountter(&liitmpp);QPaart22=littmp.QuaadPaart;/获获得中止止值dfMMinuus=(ddoubble)(QPPartt2-QQParrt1);dfT
10、Tim=ddfMiinuss/dfFFreqq;/获得得对应的的时间值值,单位位为秒whhilee(dffTimm0.0011);其定定时误差差不超过过1微秒,精度与与CPUU等机器器配置有有关。下下面的程程序用来来测试函函数Slleepp(1000)的的精确持持续时间间:LARRGE_INTTEGEERllitmmp;LONNGLOONGQPaart11,QPPartt2;douubleedffMinnus,dffFreeq,dfTTim;QueeryPPerfformmancceFrrequuenccy(&littmp);dfFFreqq=(dooublle)llitmmp.QQuaddP
11、arrt;/获获得计数数器的时时钟频率率QueeryPPerfformmancceCoountter(&liitmpp);QPaart11=littmp.QuaadPaart;/获得初初始值Sleeep(1000);QueeryPPerfformmancceCoountter(&liitmpp);QPaart22=littmp.QuaadPaart;/获获得中止止值dfMMinuus=(ddoubble)(QPPartt2-QQParrt1);dfTTim=ddfMiinuss/dfFFreqq;/获得得对应的的时间值值,单位位为秒由于于Sleeep()函数数自身的的误差,上述程程序每次次执行
12、的的结果都都会有微微小误差差。下列列代码实实现1微秒的的精确定定时:LARRGE_INTTEGEERllitmmp;LONNGLOONGQPaart11,QPPartt2;douubleedffMinnus,dffFreeq,dfTTim;QueeryPPerfformmancceFrrequuenccy(&littmp);dfFFreqq=(dooublle)llitmmp.QQuaddParrt;/获获得计数数器的时时钟频率率QueeryPPerfformmancceCoountter(&liitmpp);QPaart11=littmp.QuaadPaart;/获得初初始值doQueery
13、PPerfformmancceCoountter(&liitmpp);QPaart22=littmp.QuaadPaart;/获获得中止止值dfMMinuus=(ddoubble)(QPPartt2-QQParrt1);dfTTim=ddfMiinuss/dfFFreqq;/获得得对应的的时间值值,单位位为秒whhilee(dffTimmm_hhWndd,IDDC_TTIMEE,sttrTiime);Sleeep(10000);该线程函函数没有有参数,也不返返回函数数值。只只要m_bRuun为TRUUE,线线程一直直运行。双击IDDC_SSTARRT按钮钮,完成成该按钮钮的消息息函数:vooi
14、dCMuultiiThrreadd1Dllg:OnSStarrt()/TOODO:AdddyyourrcoontrrolnottifiicattionnhaandllercoddehhereehTThreead=CreeateeThrreadd(NUULL,00,(LPPTHRREADD_STTARTT_ROOUTIINE)ThrreaddFunnc,NUULL,00,&ThhreaadIDD);GettDlggIteem(IIDC_STAART)-EEnabbleWWinddow(FALLSE);GGetDDlgIItemm(IDDC_SSTOPP)-EnaableeWinndoww(TRR
15、UE);双击IDDC_SSTOPP按钮,完成该该按钮的的消息函函数:voiidCCMulltiTThreead11Dlgg:OOnSttop()/TOODO:Adddyyourrcoontrrolnottifiicattionnhaandllercoddehhereem_bRuun=FFALSSE;GettDlggIteem(IIDC_STAART)-EEnabbleWWinddow(TRUUE);GeetDllgIttem(IDCC_STTOP)-EEnabbleWWinddow(FALLSE);编译并运运行该例例程,体体会使用用Winn32APII编写的的多线程程。例程2MulltiTTh
16、reead22该线线程演示示了如何何传送一一个一个个整型的的参数到到一个线线程中,以及如如何等待待一个线线程完成成处理。建立一个个基于对对话框的的工程MMulttiThhreaad2,在对话话框IDDD_MMULTTITHHREAAD2_DIAALOGG中加入入一个编编辑框和和一个按按钮,IID分别别是IDDC_CCOUNNT,IDCC_STTARTT,按按钮控件件的标题题为“开始”;在MulltiTThreead22Dlgg.h文文件中添添加线程程函数声声明:voiidTThreeadFFuncc(inntiinteegerr);注意,线线程函数数的声明明应在类类CMuultiiThrrea
17、dd2Dllg的外外部。在类CMMulttiThhreaad2DDlg内内部添加加prootecctedd型变量量:HANNDLEEhTThreead;DWWORDDThhreaadIDD;分别代表表线程的的句柄和和ID。打开CllasssWizzardd,为编编辑框IIDC_COUUNT添添加innt型变变量m_nCoountt。在MuultiiThrreadd2Dllg.ccpp文文件中添添加:vvoiddThhreaadFuunc(inttinntegger)inntii;ffor(i=00;iEnnablleWiindoow(FFALSSE);WaaitFForSSinggleOObj
18、eect(hThhreaad,IINFIINITTE);GeetDllgIttem(IDCC_STTARTT)-EnaableeWinndoww(TRRUE);顺便说一一下WaaitFForSSinggleOObjeect函函数,其其函数原原型为:DWOORDWaiitFoorSiinglleObbjecct(HHANDDLEhHaandlle,DDWORRDddwMiilliiseccondds);hHanndlee为要监监视的对对象(一一般为同同步对象象,也可可以是线线程)的的句柄;dwMMillliseeconnds为为hHaandlle对象象所设置置的超时时值,单单位为毫毫秒;当当在某
19、一一线程中中调用该该函数时时,线程程暂时挂挂起,系系统监视视hHaandlle所指指向的对对象的状状态。如如果在挂挂起的ddwMiilliiseccondds毫秒秒内,线线程所等等待的对对象变为为有信号号状态,则该函函数立即即返回;如果超超时时间间已经到到达dwwMilllissecoondss毫秒,但hHHanddle所所指向的的对象还还没有变变成有信信号状态态,函数数照样返返回。参参数dwwMilllissecoondss有两个个具有特特殊意义义的值:0和INFFINIITE。若为00,则该函函数立即即返回;若为IINFIINITTE,则则线程一一直被挂挂起,直直到hHHanddle所所指
20、向的的对象变变为有信信号状态态时为止止。本例程程调用该该函数的的作用是是按下IIDC_STAART按按钮后,一直等等到线程程返回,再恢复复IDCC_STTARTT按钮正正常状态态。编译译运行该该例程并并细心体体会。例程3MulltiTThreead33传送送一个结结构体给给一个线线程函数数也是可可能的,可以通通过传送送一个指指向结构构体的指指针参数数来完成成。先定定义一个个结构体体:typeedeffsttrucctinntffirsstArrgu,loongsecconddArggu,myyTyppe,*pMyyTyppe;创建线程程时CrreatteThhreaad(NNULLL,0,th
21、rreaddFunnc,ppMyTTypee,);在thrreaddFunnc函数数内部,可以使使用“强制转转换”:intinttVallue=(ppMyTTypee)lppvoiid)-fiirsttArggu;llonggloongVValuue=(pMMyTyype)lpvvoidd)-seccondddArrgu;例程3MulltiTThreead33将演示示如何传传送一个个指向结结构体的的指针参参数。建立一个个基于对对话框的的工程MMulttiThhreaad3,在对话话框IDDD_MMULTTITHHREAAD3_DIAALOGG中加入入一个编编辑框IIDC_MILLLISSECO
22、OND,一个按按钮IDDC_SSTARRT,标标题为“开始”,一个个进度条条IDCC_PRROGRRESSS1;打开CllasssWizzardd,为编编辑框IIDC_MILLLISSECOOND添添加innt型变变量m_nMiilliiSeccondd,为进进度条IIDC_PROOGREESS11添加CPProggresssCttrl型型变量mm_cttrlPProggresss;在MulltiTThreead33Dlgg.h文文件中添添加一个个结构的的定义:strructtthhreaadInnfoUIINTnMiilliiSeccondd;CCProogreessCCtrll*ppctr
23、rlPrrogrresss;线程函数数的声明明:UUINTTThhreaadFuunc(LPVVOIDDlppParram);注意,二二者应在在类CMMulttiThhreaad3DDlg的的外部。在类CMMulttiThhreaad3DDlg内内部添加加prootecctedd型变量量:HHANDDLEhThhreaad;DWOORDThrreaddID;分别代表表线程的的句柄和和ID。在MulltiTThreead33Dlgg.cppp文件件中进行行如下操操作:定义公共共变量thrreaddInffoIInfoo;双击按按钮IDDC_SSTARRT,添添加相应应消息处处理函数数:vooid
24、CMuultiiThrreadd3Dllg:OnSStarrt()/TOODO:AdddyyourrcoontrrolnottifiicattionnhaandllercoddehhereeUpddateeDatta(TTRUEE);Inffo.nnMillliSSecoond=m_nnMillliSSecoond;Innfo.pcttrlPProggresss=&m_cctrllProogreess;hThhreaad=CCreaateTThreead(NULLL,0,(LPTTHREEAD_STAART_ROUUTINNE)TThreeadFFuncc,&Innfo,00,&Thhreaa
25、dIDD);/*GGetDDlgIItemm(IDDC_SSTARRT)-EnnablleWiindoow(FFALSSE);WaaitFForSSinggleOObjeect(hThhreaad,IINFIINITTE);GeetDllgIttem(IDCC_STTARTT)-EnaableeWinndoww(TRRUE);*/在函数BBOOLLCMMulttiThhreaad3DDlg:OnnIniitDiialoog()中添加加语句:/TOODO:Adddeextrraiinittiallizaatioonhhereem_ctrrlPrrogrresss.SeetRaangee(0,99
26、);mm_nMMillliSeeconnd=110;UpddateeDatta(FFALSSE);reeturrnTTRUEE;/retturnnTRRUEunnlesssyyousettthheffocuusttoaacoontrrol添加线程程处理函函数:UUINTTThhreaadFuunc(LPVVOIDDlppParram)thrreaddInffo*pInnfo=(thhreaadInnfo*)lppParram;foor(iinti=00;innMillliSSecoond;pIInfoo-ppctrrlPrrogrresss-SSetPPos(i);Slleepp(nTTemp
27、p);rretuurn0;顺便便补充一一点,如如果你在在voiidCCMulltiTThreead33Dlgg:OOnSttartt()函数中中添加/*/语句句,编译译运行你你就会发发现进度度条不进进行刷新新,主线线程也停停止了反反应。什什么原因因呢?这这是因为为WaiitFoorSiinglleObbjecct函数数等待子子线程(ThrreaddFunnc)结结束时,导致了了线程死死锁。因因为WaaitFForSSinggleOObjeect函函数会将将主线程程挂起(任何消消息都得得不到处处理),而子线线程ThhreaadFuunc正正在设置置进度条条,一直直在等待待主线程程将刷新新消息处处
28、理完毕毕返回才才会检测测通知事事件。这这样两个个线程都都在互相相等待,死锁发发生了,编程时时应注意意避免。例程4MulltiTThreead44该例程程测试在在Winndowws下最最多可创创建线程程的数目目。建立一个个基于对对话框的的工程MMulttiThhreaad4,在对话话框IDDD_MMULTTITHHREAAD4_DIAALOGG中加入入一个按按钮IDDC_TTESTT和一个个编辑框框IDCC_COOUNTT,按钮钮标题为为“测试”,编辑框框属性选选中Reead-onlly;在MulltiTThreead44Dlgg.cppp文件件中进行行如下操操作:添加公共共变量vvolaati
29、lleBBOOLLm_bRuunFllag=TRUUE;该变量量表示是是否还能能继续创创建线程程。添加线程程函数:DWORRDWWINAAPIthrreaddFunnc(LLPVOOIDthrreaddNumm)whhilee(m_bRuunFllag)Sleeep(30000);rretuurn0;只要mm_bRRunFFlagg变量量为TRRUE,线程一一直运行行。双击按钮钮IDCC_TEEST,添加其其响应消消息函数数:vooidCMuultiiThrreadd4Dllg:OnTTestt()DWWORDDthhreaadIDD;GGetDDlgIItemm(IDDC_TTESTT)-E
30、naableeWinndoww(FAALSEE);lonngnnCouunt=0;whiile(m_bbRunnFlaag)if(CreeateeThrreadd(NUULL,0,tthreeadFFuncc,NUULL,0,&thrreaddID)=NNULLL)m_bRuunFllag=FALLSE;breeak;eelseenCoountt+;/不断创创建线程程,直到到再不能能创建为为止mm_nCCounnt=nnCouunt;UppdatteDaata(FALLSE);SSleeep(550000);/延时时5秒,等等待所有有创建的的线程结结束GGetDDlgIItemm(IDDC_T
31、TESTT)-EnaableeWinndoww(TRRUE);mm_bRRunFFlagg=TRRUE;五、MFFC对多多线程编编程的支支持MFC中中有两类类线程,分别称称之为工工作者线线程和用用户界面面线程。二者的的主要区区别在于于工作者者线程没没有消息息循环,而用户户界面线线程有自自己的消消息队列列和消息息循环。工工作者线线程没有有消息机机制,通通常用来来执行后后台计算算和维护护任务,如冗长长的计算算过程,打印机机的后台台打印等等。用户户界面线线程一般般用于处处理独立立于其他他线程执执行之外外的用户户输入,响应用用户及系系统所产产生的事事件和消消息等。但对于于Winn32的的APII编程而
32、而言,这这两种线线程是没没有区别别的,它它们都只只需线程程的启动动地址即即可启动动线程来来执行任任务。在MMFC中中,一般般用全局局函数AAfxBBegiinThhreaad()来创建建并初始始化一个个线程的的运行,该函数数有两种种重载形形式,分分别用于于创建工工作者线线程和用用户界面面线程。两种重重载函数数原型和和参数分分别说明明如下:(1)CWiinThhreaad*AfxxBegginTThreead(AFXX_THHREAADPRROCpfnnThrreaddProoc,LPVVOIDDpPParaam,nPrriorrityy=THHREAAD_PPRIOORITTY_NNORMMA
33、L,UIINTnSttackkSizze=00,DDWORRDddwCrreatteFllagss=0,LPPSECCURIITY_ATTTRIBBUTEESllpSeecurrityyAtttrs=NULLL);PfnTThreeadPProcc:指向向工作者者线程的的执行函函数的指指针,线线程函数数原型必必须声明明如下:UIINTExeecuttinggFunnctiion(LPVVOIDDpPParaam);请注意,ExeecuttinggFunnctiion()应返返回一个个UINNT类型型的值,用以指指明该函函数结束束的原因因。一般般情况下下,返回回0表明执执行成功功。pPaaram
34、m:传递递给线程程函数的的一个332位参参数,执执行函数数将用某某种方式式解释该该值。它它可以是是数值,或是指指向一个个结构的的指针,甚至可可以被忽忽略;nPrriorrityy:线程程的优先先级。如如果为00,则线线程与其其父线程程具有相相同的优优先级;nSttackkSizze:线线程为自自己分配配堆栈的的大小,其单位位为字节节。如果果nSttackkSizze被设设为0,则线线程的堆堆栈被设设置成与与父线程程堆栈相相同大小小;dwCCreaateFFlaggs:如如果为00,则线线程在创创建后立立刻开始始执行。如果为为CREEATEE_SUUSPEEND,则线程程在创建建后立刻刻被挂起起
35、;lpSSecuurittyAtttrss:线程程的安全全属性指指针,一一般为NNULLL;(22)CCWinnThrreadd*AAfxBBegiinThhreaad(CCRunntimmeCllasss*ppThrreaddClaass,inntnnPriioriity=THRREADD_PRRIORRITYY_NOORMAAL,UINNTnnStaackSSizee=0,DWWORDDdwwCreeateeFlaags=0,LPSSECUURITTY_AATTRRIBUUTESSlppSeccuriityAAttrrs=NNULLL);pThrreaddClaass是指向向CWWinTT
36、hreead的一个个导出类类的运行行时类对对象的指指针,该该导出类类定义了了被创建建的用户户界面线线程的启启动、退退出等;其它参参数的意意义同形形式1。使用用函数的的这个原原型生成成的线程程也有消消息机制制,在以以后的例例子中我我们将发发现同主主线程的的机制几几乎一样样。下面我们们对CWWinTThreead类类的数据据成员及及常用函函数进行行简要说说明。m_hTThreead:当前线线程的句句柄;m_nnThrreaddID:当前线线程的IID;m_ppMaiinWnnd:指指向应用用程序主主窗口的的指针BOOOLCCWinnThrreadd:CCreaateTThreead(DWOORDd
37、wCCreaateFFlaggs=00,UIINTnSttackkSizze=00,LPPSECCURIITY_ATTTRIBBUTEESllpSeecurrityyAtttrs=NULLL);该函函数中的的dwCCreaateFFlaggs、nSttackkSizze、lpSSecuurittyAtttrss参数和和APII函数CrreatteThhreaad中的的对应参参数有相相同含义义,该函函数执行行成功,返回非非0值,否否则返回回0。一一般情况况下,调调用AffxBeeginnThrreadd()来来一次性性地创建建并启动动一个线线程,但但是也可可以通过过两步法法来创建建线程:首先创创
38、建CWWinTThreead类类的一个个对象,然后调调用该对对象的成成员函数数CreeateeThrreadd()来来启动该该线程。virttuallBOOOLCWiinThhreaad:IniitInnstaancee();重载载该函数数以控制制用户界界面线程程实例的的初始化化。初始始化成功功则返回回非0值,否否则返回回0。用户户界面线线程经常常重载该该函数,工作者者线程一一般不使使用InnitIInsttancce()。virrtuaaliintCWiinThhreaad:ExiitInnstaancee();在线线程终结结前重载载该函数数进行一一些必要要的清理理工作。该函数数返回线线程的
39、退退出码,0表示执执行成功功,非00值用来来标识各各种错误误。同IInittInsstannce()成员员函数一一样,该该函数也也只适用用于用户户界面线线程。六、MFFC多线线程编程程实例在VVisuualC+6.0编程程环境中中,我们们既可以以编写CC风格的的32位Winn32应应用程序序,也可可以利用用MFCC类库编编写C+风格格的应用用程序,二者各各有其优优缺点。基于WWin332的应应用程序序执行代代码小巧巧,运行行效率高高,但要要求程序序员编写写的代码码较多,且需要要管理系系统提供供给程序序的所有有资源;而基于于MFCC类库的的应用程程序可以以快速建建立起应应用程序序,类库库为程序序
40、员提供供了大量量的封装装类,而而且DeevellopeerSStuddio为为程序员员提供了了一些工工具来管管理用户户源程序序,其缺缺点是类类库代码码很庞大大。由于于使用类类库所带带来的快快速、简简捷和功功能强大大等优越越性,因因此除非非有特殊殊的需要要,否则则VissuallC+推荐荐使用MMFC类类库进行行程序开开发。我们知道道,MFFC中的的线程分分为两种种:用户户界面线线程和工工作者线线程。我我们将分分别举例例说明。用MFFC类类库编程程实现工工作者线线程例程5MulltiTThreead55为了与WWin332AAPI对对照,我我们使用用MFCC类库库编程实实现例程程3MMultti
41、Thhreaad3。建立一个个基于对对话框的的工程MMulttiThhreaad5,在对话话框IDDD_MMULTTITHHREAAD5_DIAALOGG中加入入一个编编辑框IIDC_MILLLISSECOOND,一个按按钮IDDC_SSTARRT,标标题为“开始”,一个个进度条条IDCC_PRROGRRESSS1;打开CllasssWizzardd,为编编辑框IIDC_MILLLISSECOOND添添加innt型变变量m_nMiilliiSeccondd,为进进度条IIDC_PROOGREESS11添加CPProggresssCttrl型型变量mm_cttrlPProggresss;在Mul
42、ltiTThreead55Dlgg.h文文件中添添加一个个结构的的定义:strructtthhreaadInnfoUIINTnMiilliiSeccondd;CCProogreessCCtrll*ppctrrlPrrogrresss;线程函数数的声明明:UIINTThrreaddFunnc(LLPVOOIDlpPParaam);注意意,二者者应在类类CMuultiiThrreadd5Dllg的外外部。在类CMMulttiThhreaad5DDlg内内部添加加prootecctedd型变量量:CWinnThrreadd*ppThrreadd;在在MulltiTThreead55Dlgg.cppp
43、文件件中进行行如下操操作:定定义公共共变量:thrreaddInffoIInfoo;双双击按钮钮IDCC_STTARTT,添加加相应消消息处理理函数:voiddCMMulttiThhreaad5DDlg:OnnStaart()/TOODO:AdddyyourrcoontrrolnottifiicattionnhaandllercoddehhereeUpddateeDatta(TTRUEE);Inffo.nnMillliSSecoond=m_nnMillliSSecoond;Innfo.pcttrlPProggresss=&m_cctrllProogreess;pThhreaad=AAfxBBe
44、giinThhreaad(TThreeadFFuncc,&Innfo);在函数BBOOLLCMMulttiThhreaad3DDlg:OnnIniitDiialoog()中添加加语句:/TOODO:Adddeextrraiinittiallizaatioonhhereem_ctrrlPrrogrresss.SeetRaangee(0,99);mm_nMMillliSeeconnd=110;UpddateeDatta(FFALSSE);reeturrnTTRUEE;/retturnnTRRUEunnlesssyyousettthheffocuusttoaacoontrrol添加线程程处理函函数:
45、UINNTTThreeadFFuncc(LPPVOIIDllpPaaramm)thhreaadInnfo*pIInfoo=(tthreeadIInfoo*)llpPaaramm;ffor(intti=0;iinnMillliSSecoond;pIInfoo-ppctrrlPrrogrresss-SSetPPos(i);Slleepp(nTTempp);rretuurn0;用MFFC类类库编程程实现用用户界面面线程创建用户户界面线线程的步步骤:使用CllasssWizzardd创建类类CWiinThhreaad的派派生类(以CUUIThhreaad类为为例)claassCUIIThrreadd:
46、pubbliccCWWinTThreeadDEECLAARE_DYNNCREEATEE(CUUIThhreaad)pprottectted:CUUIThhreaad();/prooteccteddcoonsttrucctorrussedbydynnamiicccreaatioon/AAttrribuutesspubblicc:/OOperratiionsspubblicc:/OOverrriddes/ClaassWWizaardgenneraateddviirtuualfunnctiionoveerriidess/AFFX_VVIRTTUALL(CUUIThhreaad)pubblicc:vv
47、irttuallBOOOLIniitInnstaancee();viirtuualinttExxitIInsttancce();/AFXX_VIIRTUUAL/IImpllemeentaatioonprroteecteed:virrtuaalCUIIThrreadd();/Genneraateddmeessaagemappfuuncttionns/AAFX_MSGG(CUUIThhreaad)/NOOTE-ttheClaassWWizaardwilllaaddanddreemovvemmembberfunnctiionssheere./AAFX_MSGGDECCLARRE_MMESSSAGEE
48、_MAAP();重载函数数IniitInnstaancee()和和ExiitInnstaancee()。BOOOLCUIIThrreadd:IInittInsstannce()CFFrammeWnnd*wndd=neewCCFraameWWnd;wnnd-Creeatee(NUULL,UIIThhreaadWWinddow);wndd-SShowwWinndoww(SWW_SHHOW);wwnd-UppdatteWiindoow();mm_pMMainnWndd=wnnd;retturnnTRRUE;创建新的的用户界界面线程程vooidCUIIThrreaddDlgg:OOnBuuttoon1
49、()CUUIThhreaad*pThhreaad=nnewCUIIThrreadd();pTThreead-CrreatteThhreaad();请注意以以下两点点:A、在UUIThhreaadDllg.ccpp的的开头加加入语句句:#inccluddeUITThreead.hBB、把UIIThrreadd.h中中类CUUIThhreaad()的构造造函数的的特性由由prroteecteed改改为ppubllic。用用户界面面线程的的执行次次序与应应用程序序主线程程相同,首先调调用用户户界面线线程类的的IniitInnstaancee()函函数,如如果返回回TRUUE,继继续调用用线程的的Ru
50、nn()函函数,该该函数的的作用是是运行一一个标准准的消息息循环,并且当当收到WWM_QQUITT消息后后中断,在消息息循环过过程中,Runn()函函数检测测到线程程空闲时时(没有有消息),也将将调用OOnIddle()函数数,最后后Runn()函函数返回回,MFFC调用用ExiitInnstaancee()函函数清理理资源。你你可以创创建一个个没有界界面而有有消息循循环的线线程,例例如:你你可以从从CWiinThhreaad派生生一个新新类,在在IniitInnstaancee函数中中完成某某项任务务并返回回FALLSE,这表示示仅执行行IniitInnstaancee函数中中的任务务而不执
51、执行消息息循环,你可以以通过这这种方法法,完成成一个工工作者线线程的功功能。例程6MulltiTThreead66建立一个个基于对对话框的的工程MMulttiThhreaad6,在对话话框IDDD_MMULTTITHHREAAD6_DIAALOGG中加入入一个按按钮IDDC_UUI_TTHREEAD,标题为为“用户界界面线程程”右击工程程并选中中“NeewCClasss”为工程程添加基基类为CCWinnThrreadd派生线线程类CCUITThreead。给工程程添加新新对话框框IDDD_UIITHRREADDDLGG,标题题为“线程对对话框”。为对话话框IDDD_UUITHHREAADDLL
52、G创建建一个基基于CDDiallog的的类CUUIThhreaadDllg。使使用CllasssWizzardd为CUIIThrreaddDlgg类添加加WM_LBUUTTOONDOOWN消消息的处处理函数数OnLLButttonnDowwn,如如下:voiidCCUITThreeadDDlg:OnnLBuuttoonDoown(UINNTnnFlaags,CPPoinntppoinnt)AffxMeessaageBBox(YoouCClicckeddThheLLefttBuuttoon!);CDiialoog:OnLLButttonnDowwn(nnFlaags,poointt);在UITT
53、hreead.h中添添加#inccluddeUITThreeadDDlg.h并并在CUUIThhreaad类中中添加pprottectted变变量CUUIThhreaadmm_dllg:cllasssCUUIThhreaad:puubliicCCWinnThrreaddDEECLAARE_DYNNCREEATEE(CUUIThhreaad)pprottectted:CUUIThhreaad();/prooteccteddcoonsttrucctorrussedbydynnamiicccreaatioon/AAttrribuutesspubblicc:/OOperratiionsspubblic
54、c:/OOverrriddes/ClaassWWizaardgenneraateddviirtuualfunnctiionoveerriidess/AFFX_VVIRTTUALL(CUUIThhreaad)pubblicc:vvirttuallBOOOLIniitInnstaancee();viirtuualinttExxitIInsttancce();/AFXX_VIIRTUUAL/IImpllemeentaatioonprroteecteed:CUIIThrreaddDlggm_dlgg;vvirttuallCCUITThreead();/Genneraateddmeessaagemapp
55、fuuncttionns/AAFX_MSGG(CUUIThhreaad)/NOOTE-ttheClaassWWizaardwilllaaddanddreemovvemmembberfunnctiionssheere./AAFX_MSGGDECCLARRE_MMESSSAGEE_MAAP();分别重载载IniitInnstaancee()函函数和EExittInsstannce()函数数:BBOOLLCUUIThhreaad:IniitInnstaancee()m_dlgg.Crreatte(IIDD_UITTHREEADDDLG);mm_dllg.SShowwWinndoww(SWW_SHHO
56、W);mm_pMMainnWndd=&mm_dllg;retturnnTRRUE;intCUIIThrreadd:EExittInsstannce()m_dlgg.DeestrroyWWinddow();retturnnCWWinTThreead:ExxitIInsttancce();双击按钮钮IDCC_UII_THHREAAD,添添加消息息响应函函数:voiidCCMulltiTThreead66Dlgg:OOnUiiThrreadd()CWWinTThreead*pTThreead=AfxxBegginTThreead(RUNNTIMME_CCLASSS(CCUITThreead);并在M
57、uultiiThrreadd6Dllg.ccpp的的开头添添加:#inncluudeUIIThrreadd.h好了了,编译译并运行行程序吧吧。每单单击一次次“用户界界面线程程”按钮,都会弹弹出一个个线程对对话框,在任何何一个线线程对话话框内按按下鼠标标左键,都会弹弹出一个个消息框框。七、线程间间通讯一般般而言,应用程程序中的的一个次次要线程程总是为为主线程程执行特特定的任任务,这样,主线程程和次要要线程间间必定有有一个信信息传递递的渠道道,也就是是主线程程和次要要线程间间要进行行通信。这种线线程间的的通信不不但是难难以避免免的,而而且在多多线程编编程中也也是复杂杂和频繁繁的,下下面将进进行说明
58、明。使用全局局变量进进行通信信由于属于于同一个个进程的的各个线线程共享享操作系系统分配配该进程程的资源源,故解解决线程程间通信信最简单单的一种种方法是是使用全全局变量量。对于于标准类类型的全全局变量量,我们们建议使使用voolattilee修饰饰符,它它告诉编编译器无无需对该该变量作作任何的的优化,即无需需将它放放到一个个寄存器器中,并并且该值值可被外外部改变变。如果果线程间间所需传传递的信信息较复复杂,我我们可以以定义一一个结构构,通过过传递指指向该结结构的指指针进行行传递信信息。使用自自定义消消息我们可以以在一个个线程的的执行函函数中向向另一个个线程发发送自定定义的消消息来达达到通信信的目
59、的的。一个个线程向向另外一一个线程程发送消消息是通通过操作作系统实实现的。利用WWinddowss操作系系统的消消息驱动动机制,当一个个线程发发出一条条消息时时,操作作系统首首先接收收到该消消息,然然后把该该消息转转发给目目标线程程,接收收消息的的线程必必须已经经建立了了消息循循环。例程7MulltiTThreead77该例例程演示示了如何何使用自自定义消消息进行行线程间间通信。首先,主线程程向CCCalcculaateTThreead线线程发送送消息WWM_CCALCCULAATE,CCaalcuulatteThhreaad线程程收到消消息后进进行计算算,再向向主线程程发送WWM_DDISP
60、PLAYY消息,主线程程收到该该消息后后显示计计算结果果。建立一个个基于对对话框的的工程MMulttiThhreaad7,在对话话框IDDD_MMULTTITHHREAAD7_DIAALOGG中加入入三个单单选按钮钮IDCC_RAADIOO1,IDCC_RAADIOO2,IDCC_RAADIOO3,标标题分别别为1+2+33+4+.+100,1+22+3+4+.+50,1+22+3+4+.+1000。加入入按钮IIDC_SUMM,标题题为“求和”。加入入标签框框IDCC_STTATUUS,属属性选中中“边框”;在MulltiTThreead77Dlgg.h中中定义如如下变量量:prootecc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 上海工程技术大学《安全法规》2025-2026学年第一学期期末试卷(A卷)
- 上海工程技术大学《Android 移动应用开发》2025-2026学年第一学期期末试卷(A卷)
- 上海工商职业技术学院《安全系统工程》2025-2026学年第一学期期末试卷(B卷)
- 上海工商职业技术学院《安全原理》2025-2026学年第一学期期末试卷(B卷)
- 欣赏 管弦乐曲《马刀舞曲》说课稿2025学年小学音乐花城版六年级下册-花城版
- 胫骨骨折的康复护理法律法规
- 上饶卫生健康职业学院《安全检测技术》2025-2026学年第一学期期末试卷(B卷)
- 上饶卫生健康职业学院《Android 移动应用开发》2025-2026学年第一学期期末试卷(A卷)
- 上海音乐学院《安全管理》2025-2026学年第一学期期末试卷(B卷)
- 26年检测职称考试考点梳理
- 盆腔炎性疾病诊疗规范
- 港口码头运营与管理手册
- 2026年考研政治真题及答案解析(完整版)
- 轨道交通系统运营与维护手册(标准版)
- 小学科学新教科版二年级下册2.5.设计钓鱼玩具 练习题(附参考答案和解析)2026春
- 2025年中国铁路武汉局集团有限公司招聘高校毕业生1291人(二)笔试参考题库附带答案详解
- 2026年设备安装质量员考试题库(附答案)
- 2026年幼儿教师特岗考试试题
- 2026中原豫资投资控股集团秋招试题及答案
- 2026中国旅游集团总部及所属企业岗位招聘9人参考题库附答案
- 2026年上海市黄埔区初三上学期一模数学试卷和参考答案
评论
0/150
提交评论