版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
MultithreadedProgrammingWiththeWin32APIAndrewTuckerDebuggerDevelopmentLeadMarch13,1998WhatWeWillCover
IntrotoMultithreadedConceptsStartingandStoppingThreadsSynchronizationDebuggingandTestingIssuesInterprocessCommunicationAdvancedTopicsandAdditionalResourcesCaveatsMultithreadedfeaturesetsdifferbetweenNT,Win95andCEandversionsofthesameOSIntrotoMultithreadedConceptsWhatisathread?“pathofexecutioninaprocess”ownedbyasingleprocessallprocesseshavemainthread,somehavemorehasfullaccesstoprocessaddressspaceProcess1Process2ProcessNMainT1T2T3MainMainT1OperatingSystemIntrotoMultithreadedConceptsScheduling-cooperativevspreemptivePreemptive-allowathreadtoexecuteforaspecifiedamountoftimeandthenautomaticallyperformsa“contextswitch”tochangetoanewthread(e.G.NT,win95,WCE)Cooperative-performscontextswitchonlywhentheuserspecifies(“manuallyscheduled”)Win16isneither:multitasking,butnotmultithreadStartingandStoppingThreadsCreateThreadAPIHANDLECreateThread(LPSECURITY_ATTRIBUTESlpsa, //pointertothreadsecurityattributes DWORDdwStackSize, //initialthreadstacksize,inbytes LPTHREAD_START_ROUTINElpStartAddress, //pointertothreadfunction LPVOIDlpParameter, //argumentfornewthread DWORDdwCreationFlags, //creationflags LPDWORDlpThreadId //pointertoreturnedthreadidentifier );_beginthreadexCRTfunctionunsignedlong_beginthreadex(void*security, unsignedstack_size, unsigned(__stdcall*start_address)(void*), void*arglist, unsignedinitflag, unsigned*thrdaddr);So,what’sthedifference?StartingandStoppingThreadsDifferenceistheinitializationoftheCRTlibraryLinkingwithmultithreadedCRTisnotenoughDWORDThreadFunc(PVOIDpv){char*psz=strtok((char*)pv,“;”);while(psz){….processdata….psz=strtok(NULL.“;”);}}intmain(){//BUG-use_beginthreadextoensurethreadsafeCRTHANDLEhthrd1=CreateThread(…ThreadFunc…);HANDLEhthrd2=CreateThread(…ThreadFunc…);}_beginthreadexcreatesastructuretoensureglobalandstaticCRTvariablesarethread-specificStartingandStoppingThreadsThreadfunctionshavethefollowingprototype:
DWORDWINAPIThreadFunc(PVOIDpv);Itisveryusefultousepvasapointertoauser-definedstructuretopassextradataStartingandStoppingThreadsAreturnwillautomaticallycalltherespective_endthreadexorEndThreadAPIAreturndoesnotclosethehandlefromthecreationroutine(usermustcallCloseHandletoavoidresourceleak)Threadsshouldbeself-terminating(avoidtheTerminateThreadAPI)StartingandStoppingThreadsReasonstoavoidtheTerminateThreadAPI:Ifthetargetthreadownsacriticalsection,itwillnotbereleasedIfthetargetthreadisexecutingcertainkernelcalls,thekernelstateforthethread’sprocesscouldbeinconsistentIfthetargetthreadismanipulatingtheglobalstateofasharedDLL,thestateoftheDLLcouldbedestroyed,affectingotherusersoftheDLLStartingandStoppingThreadsUsingaC++memberasathreadfunction(fixingthe‘this’problem):classThreadedClass{public:ThreadedClass();BOOLStart();voidStop();private:HANDLEm_hThread;BOOLm_bRunning;staticUINTWINAPIStaticThreadFunc(LPVOIDlpv);DWORDMemberThreadFunc();};UINTWINAPIThreadedClass::StaticThreadFunc( LPVOIDlpv){ThreadedClass*pThis=(ThreadedClass*)lpv;returnpThis->MemberThreadFunc();}DWORDThreadedClass::MemberThreadFunc(){while(m_bRunning){…doprocessing... }}BOOLThreadedClass::Start(DWORDdwStart){UINTnTID;m_hThread=(HANDLE)_beginthreadex(NULL,0, StaticThreadFunc,this,0,&nTID)returnTRUE;}voidThreadedClass::Stop(){m_bRunning=FALSE;//waitforthreadtofinishDWORDdwExitCode;GetExitCodeThread(m_hThread,&dwExitCode);while(dwExitCode==STILL_ACTIVE){GetExitCodeThread(m_hThread,&dwExitCode);}m_hThread=0;}intmain(){
ThreadedClasstc1,tc2;tc1.Start(5);tc2.Start(5000);Sleep(3000);tc1.Stop();tc2.Stop();return0;}StartingandStoppingThreadsSuspendThreadandResumeThreadallowyoutopauseandrestartanythreadSuspensionstateisacountnotaboolean-callsshouldbebalancedExample:hittingabpinadebuggercausesallcurrentthreadstobesuspendedandresumedonsteporgoStartingandStoppingThreadsGetCurrentThreadandGetCurrentThreadIdareusefulforidentifyingcurrentthreadGetExitCodeThreadisusefulfordeterminingifathreadisstillaliveGetThreadTimesisusefulforperformanceanalysisandmeasurementSynchronizationUsedtocoordinatetheactivitiesofconcurrentlyrunningthreadsAlwaysavoidcoordinatingwithapollloopwhenpossibleforefficiencyreasonsSynchronizationInterlockedfunctionsCriticalSectionsWaitfunctionsMutexesSemaphoresEventsWaitableTimersSynchronizationInterlockedfunctions:PVOIDInterlockedCompareExchange(PVOID*destination,PVOIDExchange,PVOIDComperand) if(*Destination==Comperand) *Destination=Exchange;LONGInterlockedExchange(LPLONGTarget,LONGValue) *Target=Value;LONGInterlockedExchangeAdd(LPLONGAddend,LONGIncrement) *Addend+=Increment;LONGInterlockedDecrement(LPLONGAddend) *Addend-=1;LONGInterlockedIncrement(LPLONGAddend) *Addend+=1;Alloperationsareguaranteedtobe“atomic”-theentireroutinewillexecutew/oacontextswitchSynchronizationWhymustsimpleoperationslikeincrementinganintegerbe“atomic”?MultipleCPUinstructionsarerequiredfortheactualimplementation.Ifweretrievedavariableandwerethenpreemptedbyathreadthatchangedthatvariable,wewouldbeusingthewrongvalue.SynchronizationAcriticalsectionisatoolforguaranteeingthatonlyonethreadisexecutingasectionofcodeatanytimevoidInitializeCriticalSection(LPCRITICAL_SECTIONlpCritSec)voidDeleteCriticalSection(LPCRITICAL_SECTIONlpCritSec)voidEnterCriticalSection(LPCRITICAL_SECTIONlpCritSec)voidLeaveCriticalSection(LPCRITICAL_SECTIONlpCritSec)BOOLTryEnterCriticalSection(LPCRITICAL_SECTIONlpCritSec)Synchronization EnterCriticalSectionwillnotblockonnestedcallsaslongasthecallsareinthesamethread.CallstoLeaveCriticalSectionmuststillbebalancedSynchronization Criticalsectionexample:countingsourcelinesinmultiplefilesDWORDg_dwTotalLineCount=0;DWORDCountLinesThread(PVOIDpv){PSTRpszFileName=(PSTR)pv;DWORDdwCount;dwCount=CountSourceLines(pszFileName);EnterCriticalSection(&cs);g_dwTotalLineCount+=dwCount;LeaveCriticalSection(&cs);return0;}voidUpdateSourceLineCount(){FileNameListfnl;HANDLE*pHandleList;CRITICAL_SECTIONcs;GetFileNameList(&fnl);InitializeCriticalSection(&cs);pHandleList=malloc(sizeof(HANDLE)*fnl.Size());for(inti=0;i<FileNameList.Size();i++)pHandleList[i]=_beginthreadex(…CountLinesThread,fnl[i]…);//we’llcoverthisshortly…WaitForMultipleObjects(fnl.Size(),pHandleList,TRUE,INFINITE);DeleteCriticalSection(&cs);…processg_dwTotalLineCount...}SynchronizationWaitfunctions-allowyoutopauseuntiloneormoreobjectsbecomesignaledAtalltimes,anobjectisinoneoftwostates:signaledornonsignaledPicturesignaledasaflagbeingraisedandnonsignaledasaflagbeinglowered-thewaitfunctionsarewatchingforaflagtoberaisedSynchronizationTypesofobjectsthatcanbe“waitedon“:ProcessesThreadsConsoleInputFileChangeNotificationsMutexes*Semaphores*Events*WaitableTimers*SynchronizationProcessesandthreadsarenon-signaledatcreationandbecomesignaledwhentheyterminateSynchronizationDWORDWaitForSingleObject(HANDLEhHandle,DWORDdwMilliseconds)ReturnsWAIT_OBJECT_0ifhHandlehasbecomesignaledorWAIT_TIMEOUTifdwMillisecondselapsedandtheobjectisstillnon-signaledDWORDWaitForMultipleObjects(DWORDnCount,HANDLE*pHandles,BOOLbWaitAll,DWORDdwMilliseconds)IfbWaitAllisFALSEandoneoftheobjecthandleswassignaled,thereturnvalueminusWAIT_OBJECT_0isthearrayindexofthathandle.IfbWaitAllisTRUEandalloftheobjectsbecomesignaledthereturnvalueminusWAIT_OBJECT_0isavalidindexintothehandlearray.IfdwMillisecondselapsedandnoobjectwassignaled,WAIT_TIMEOUTisreturned.nCountcanbenomorethanMAXIMUM_WAIT_OBJECTS(currentlydefinedas64)INFINITEcanbeusedasatimeoutvalueSynchronizationMutexesprovidemutuallyexclusiveaccesstoanobject(hencethename)HANDLECreateMutex(LPSECURITY)ATTRIBUTESlpsa,BOOLbInitialOwner,LPCTSTRlpName)Ownershipisequivalenttothenonsignaledstate-ifbInitialOwnerisTRUEthecreationstateofthemutexisnonsignaledlpNameisoptionalReleaseMutexisusedtoendownershipSynchronizationWhat’sthedifferencebetweenacriticalsectionandamutex?AmutexisaOSkernelobject,andcanthusbeusedacrossprocessboundaries.AcriticalsectionislimitedtotheprocessinwhichitwascreatedSynchronizationTwomethodstogetahandletoanamedmutexcreatedbyanotherprocess:OpenMutex-returnshandletoanexistingmutexCreateMutex-createsorreturnshandletoanexistingmutex.GetLastErrorwillreturnERROR_ALREADY_EXISTSforthelattercaseSynchronizationComparingmutexandcriticalsectionperformanceSynchronizationAmutexwillnotblockonnestedcallsaslongastheyareinthesamethread.ReleaseMutexcallsmuststillbebalancedExamplesofwhentouseamutex:ErrorloggingsystemthatcanbeusedfromanyprocessDetectingmultipleinstancesofanapplicationSynchronizationSemaphoresallowaccesstoaresourcetobelimitedtoafixednumberHANDLECreateSemaphore(LPSECURITY_ATTRIBUTElpsa,LONGcSemInitial,LONGcSemMax,LPCTSTRlpName)SemaphoresareinthesignaledstatewhentheiravailablecountisgreaterthanzeroReleaseSemaphoreisusedtodecrementusageConceptually,amutexisabinarysemaphoreSynchronizationNamedsemaphorescanbeusedacrossprocessboundarieswithOpenSemaphoreandCreateSemaphoreCanbeusedtosolvetheclassic“singlewriter/multiplereaders”problemSynchronizationExample:limitingnumberofentriesinaqueueconstintQUEUE_SIZE=5;HANDLEg_hSem=NULL;longg_iCurSize=0;UINTWINAPIPrintJob(PVOIDpv){WaitForSingleObject(g_hSem,INFINITE);InterlockedIncrement(&g_iCurSize);printf("%08lX-enteredqueue:size=%d\n",GetCurrentThreadId(),g_iCurSize);Sleep(500);//printjob....InterlockedDecrement(&g_iCurSize);longlPrev;ReleaseSemaphore(g_hSem,1,&lPrev);return0;}intmain(){constintMAX_THREADS=64;HANDLEhThreads[MAX_THREADS];g_hSem=CreateSemaphore(NULL,QUEUE_SIZE,QUEUE_SIZE,NULL);UINTdwTID;for(inti=0;i<MAX_THREADS;i++)hThreads[i]=(HANDLE)_beginthreadex(NULL,0,PrintJob,NULL,0,&dwTID);WaitForMultipleObjects(MAX_THREADS,hThreads,TRUE,INFINITE);return0;}Synchronization EventsprovidenotificationwhensomeconditionhasbeenmetHANDLECreateEvent(LPSECURITY_ATTRIBUTESlpsa,BOOLbManualReset,BOOLbInitialState,LPCTSTRlpName)IfbInitialStateisTRUE,objectiscreatedinthesignaledstatebManualResetspecifiesthetypeofeventrequestedSynchronizationTwokindsofeventobjects:Autoreset-whensignaleditisautomaticallychangedtoanonsignaledstateafterasinglewaitingthreadhasbeenreleasedManualreset-whensignaleditremainsinthesignaledstateuntilitismanuallychangedtothenonsignaledstateSynchronizationNamedeventobjectscanbeusedacrossprocessboundarieswithOpenEventandCreateEventSetEventsetstheobjectstatetosignaledResetEventsetstheobjectstatetononsignaledPulseEventconceptuallycallsSetEvent/ResetEventsequentially,but...Synchronization PulseEventvsSetEventSynchronizationExample:displayingOutputDebugStringtextwithoutadebuggerintmain(){HANDLEhAckEvent,hReadyEvent;PSTRpszBuffer;hAckEvent=CreateEvent(NULL,FALSE,FALSE,“DBWIN_BUFFER_READY”);if(GetLastError()==ERROR_ALREADY_EXISTS){//handlemultipleinstancecase}hReadyEvent=CreateEvent(NULL,FALSE,FALSE,“DBWIN_DATA_READY”);pszBuffer=/*getpointertodatainmemorymappedfile*/;
SetEvent(hAckEvent);while(TRUE){intret=WaitForSingleObject(hReadyEvent,INFINITE);if(ret!=WAIT_OBJECT_0){//handleerror}else{printf(pszBuffer);SetEvent(hAckEvent);}}}SynchronizationWaitabletimersarekernelobjectsthatprovideasignalataspecifiedtimeintervalHANDLECreateWaitableTimer(LPSECURITY_ATTRIBUTESlpsa,BOOLbManualReset,LPCTSTRlpName)Manual/autoresetbehaviorisidenticaltoeventsTimeintervalisspecifiedwithSetWaitableTimerSynchronizationBOOLSetWaitableTimer(HANDLEhTimer,LARGE_INTEGER*pDueTime,LONGlPeriod,PTIMERACPROUTINEpfnCompletion,PVOIDpArg,BOOLfResume)pDueTimespecifieswhenthetimershouldgooffforthefirsttime(positiveisabsolute,negativeisrelative)lPeriodspecifieshowfrequentlytogooffaftertheinitialtimefResumecontrolswhetherthesystemisawakenedwhentimerissignaledSynchronizationConsecutivecallstoSetWaitableTimeroverwriteeachotherCancelWaitabletimerstopsthetimersothatitwillnotgooffagain(unlessSetWaitableTimeriscalled)SynchronizationExample:firinganeventeveryNsecondsconstintMAX_TIMES=3;constintN=10;DWORDWINAPIThreadFunc(PVOIDpv){HANDLEhTimer=(HANDLE)pv;intiCount=0;DWORDdwErr=0;while(TRUE){if(WaitForSingleObject(hTimer,INFINITE)==WAIT_OBJECT_0){…handletimerevent...if(++iCount>=MAX_TIMES)break;
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026江苏无锡市新吴区新瑞医院(上海瑞金医院无锡分院)招聘高层次人才43人备考题库及参考答案详解一套
- 2026贵州工贸职业学院面向社会招聘专任教师16人备考题库带答案详解
- 2026四川阿坝州阿坝县移动公司招聘4人备考题库完整参考答案详解
- 2026河南郑州四六〇医院招聘61人备考题库及1套完整答案详解
- 大庆宝石花物业租赁合同样本
- 2026富德生命人寿台州中心支公司招聘正式员工3人备考题库含答案详解
- 简约型租赁合同模板
- 2026年充电设备销售代理合同三篇
- 装配式混凝土住宅结构优化实施方案
- 构件堆放与成品保护方案
- 2025四川泸州交通物流集团有限公司及下属公司招聘12人笔试参考题库附带答案详解
- 危险作业审批培训
- 高端书画活动方案
- (正式版)DB54∕T 0428-2025 《“一河(湖)一策”方案编制规程》
- 地贫防控知识培训课件
- GB/T 26941-2025隔离栅
- 人工智能概论课程教学大纲
- 2025年江西省中级档案职称考试(档案事业概论)经典试题及答案
- 新疆公务员面试题目及答案
- 物理与现代军事科技
- 2024年广西建设职业技术学院聘用人员招聘考试真题
评论
0/150
提交评论