軟件工具與環(huán)境課件_第1頁
軟件工具與環(huán)境課件_第2頁
軟件工具與環(huán)境課件_第3頁
軟件工具與環(huán)境課件_第4頁
軟件工具與環(huán)境課件_第5頁
已閱讀5頁,還剩69頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

軟件工具與環(huán)境第二章多任務(wù)與多線程編程軟件工具與環(huán)境第二章1一、Windows程序的生與死在了解Windows程序的架構(gòu)以及它與Windows系統(tǒng)之間的關(guān)系后,對Windows消息種類以及產(chǎn)生時機(jī)的透徹了解,正是程序設(shè)計(jì)的關(guān)鍵。下面以窗口的產(chǎn)生與死亡,說明消息的產(chǎn)生與傳遞,以及應(yīng)用程序的生與死。一、Windows程序的生與死在了解Wind21、程序初始化過程中調(diào)用CreateWindow,為程序建立了一個窗口,作為程序的屏幕舞臺。CreateWindow產(chǎn)生窗口之后會送出WM_CREATE直接給窗口函數(shù),后者于是可以在此時做些初始化操作(例如配置內(nèi)存、打開文件、讀初始數(shù)據(jù)等。1、程序初始化過程中調(diào)用CreateWindow,為程序建立32、在程序活著的過程中,不斷以GetMessage從消息隊(duì)列中獲取消息。如果這個消息是WM_QUIT,GetMessage會返回0而結(jié)束while循環(huán),進(jìn)而結(jié)束整個程序。3、DispatchMessage通過WindowsUSER模塊的協(xié)助和監(jiān)督,把消息分發(fā)給窗口函數(shù)。消息將在該處被判別并處理。2、在程序活著的過程中,不斷以GetMessage從消息隊(duì)列44、程序不斷進(jìn)行上述2和3的操作。5、當(dāng)操作者按下系統(tǒng)菜單中的Close命令項(xiàng)時,系統(tǒng)送出WM_CLOSE。通常程序的窗口函數(shù)不攔截此消息,于是DefWindowProc處理它。6、DefWindowProc收到WM_CLOSE后調(diào)用DestroyWindow把窗口清除。DefWindowProc本身又會送出WM_DESTROY。4、程序不斷進(jìn)行上述2和3的操作。5、當(dāng)操作者按下系統(tǒng)菜單中57、程序?qū)W_DESTROY的標(biāo)準(zhǔn)反應(yīng)是調(diào)用PostQuitMessage。8、PostQuitMessage沒有什么操作,只送出WM_QUIT消息,準(zhǔn)備讓消息循環(huán)中的GetMessage獲取此消息,結(jié)束消息循環(huán)。7、程序?qū)W_DESTROY的標(biāo)準(zhǔn)反應(yīng)是調(diào)用PostQui6二、空閑時間的處理1、空閑時間的概念所謂空閑時間(idletime)是指“系統(tǒng)中沒有任何消息等待處理”的時間。例如沒有任何程序使用定時器(timer,它會定時送來WM_TIMER),使用者也沒有按鍵盤和鼠標(biāo)或操作任何外設(shè),那么系統(tǒng)就處于所謂的空閑時間。二、空閑時間的處理1、空閑時間的概念所謂空閑72、空閑時間的處理空閑時間經(jīng)常發(fā)生。后臺工作最適合在空閑時間完成。傳統(tǒng)的SDK程序如果要處理空閑時間,可以用下列循環(huán)取代WinMain中的傳統(tǒng)消息循環(huán)(見圖1)2、空閑時間的處理空閑時間經(jīng)常發(fā)生。后臺工作8原因是PeekMessage和GetMessage的性質(zhì)不同:它們都是從消息隊(duì)列中獲取消息,如果沒有消息,程序的主執(zhí)行線程(primarythread,是一個UI執(zhí)行線程)會被操作系統(tǒng)掛起。當(dāng)操作系統(tǒng)再次回來照顧這一執(zhí)行線程時,發(fā)現(xiàn)消息隊(duì)列中仍然是空的,這時兩個函數(shù)的行為就不同了:原因是PeekMessage和GetMess9(1)GetMessage會過門不入,于是操作系統(tǒng)再去照顧其它程序。(2)PeekMessage會取回控制權(quán),使程序得以執(zhí)行一段時間。于是上述消息循環(huán)進(jìn)入OnIdle函數(shù)中。(1)GetMessage會過門不入,于是操作系統(tǒng)再去照顧其10三、Windows的多任務(wù)1、Windows3.X的協(xié)同式多任務(wù)

Windows3.X都允許同時執(zhí)行多個程序。但分享CPU是程序的責(zé)任(即應(yīng)用程序具有對CPU的控制權(quán))。如果有一個程序不放棄CPU(許多程序采用傳統(tǒng)的消息循環(huán),而拒絕與其它程序共享資源),其它程序只有掛起而無法響應(yīng)操作。三、Windows的多任務(wù)1、Windows3.X的協(xié)同式112、Windows9X的搶先式多任務(wù)操作系統(tǒng)能夠強(qiáng)迫應(yīng)用程序把CPU分享給其它程序。即程序?qū)PU的占用時間由系統(tǒng)控制,系統(tǒng)為每個程序分配一定的CPU時間,當(dāng)程序的運(yùn)行超過規(guī)定時間后,系統(tǒng)就會中斷該程序并把CPU控制權(quán)讓給其它程序。2、Windows9X的搶先式多任務(wù)操作系統(tǒng)123、多線程多任務(wù)在Win32系統(tǒng)中,執(zhí)行一個程序,必然會產(chǎn)生一個進(jìn)程;當(dāng)一個進(jìn)程建立后,主線程也產(chǎn)生了。多任務(wù)是指系統(tǒng)可以同時運(yùn)行多個進(jìn)程,而每個進(jìn)程也可同時執(zhí)行多個線程。一個程序可以運(yùn)行多個線程,每個線程獨(dú)立地執(zhí)行程序代碼中的一組語句。3、多線程多任務(wù)在Win32系統(tǒng)中,執(zhí)行一個13四、進(jìn)程與線程通常用進(jìn)程(process)表示一個執(zhí)行中的程序,并認(rèn)為它是CPU調(diào)度單位。事實(shí)上線程(thread)才是調(diào)度單位。進(jìn)程是應(yīng)用程序的運(yùn)行實(shí)例。每個進(jìn)程都有自己私有的虛擬地址空間。每個進(jìn)程都有一個主線程,但可以建立另外的線程。進(jìn)程中的線程是并行執(zhí)行的,各線程占用CPU的時間由系統(tǒng)決定。四、進(jìn)程與線程通常用進(jìn)程(process)表14線程是Windows9X/NT系統(tǒng)調(diào)度分配CPU時間的基本單位。進(jìn)程至少有一個線程,也可以另外增加線程。系統(tǒng)為每個線程分配一個CPU時間片(約20ms),系統(tǒng)不停地在各個線程之間切換。線程只有在分配的時間片內(nèi)才有對CPU的控制權(quán)線程是Windows9X/NT系統(tǒng)調(diào)度分配C151、核心對象核心對象是系統(tǒng)的一種資源,系統(tǒng)對象一但產(chǎn)生,任何應(yīng)用程序都可以開啟并使用該對象。系統(tǒng)給予核心對象一個計(jì)數(shù)值作為管理之用。核心對象包括下列幾種:(見圖2)1、核心對象核心對象是系統(tǒng)的一種資源,系統(tǒng)對16這些核心對象的產(chǎn)生方式(使用的API)不同,但都會獲得一個handle作為識別;每被使用一次,其對應(yīng)的計(jì)數(shù)值就增1。核心對象的結(jié)束方式相當(dāng)一致,調(diào)用CloseHandle即可。Process對象不是用來執(zhí)行程序代碼的;它只是一個數(shù)據(jù)結(jié)構(gòu),系統(tǒng)用它來管理進(jìn)程。程序代碼的執(zhí)行是線程的工作。這些核心對象的產(chǎn)生方式(使用的API)不同,172、進(jìn)程的產(chǎn)生和死亡執(zhí)行一個程序,必然會產(chǎn)生一個進(jìn)程(process)。最直接的程序執(zhí)行方式就是在shell(如Windows9X的資源管理器)中用鼠標(biāo)雙擊某一個可執(zhí)行文件圖標(biāo)(如為app.exe),運(yùn)行起來的app進(jìn)程其實(shí)就是shell調(diào)用CreateProcess激活的。整個執(zhí)行流程如下:2、進(jìn)程的產(chǎn)生和死亡執(zhí)行一個程序,必然會產(chǎn)生18(1)shell調(diào)用CreateProcess激活app.exe(2)系統(tǒng)產(chǎn)生一個進(jìn)程核心對象,計(jì)數(shù)值為1。(3)系統(tǒng)為此進(jìn)程建立一個4GB地址空間。(4)加載器將必要的碼加載到上述地址空間中,包括app.exe的程序、數(shù)據(jù),以及所需的動態(tài)鏈接庫(dlls).(1)shell調(diào)用CreateProcess激活app.e19(5)系統(tǒng)為此進(jìn)程建立一個線程,稱為主線程(primarythread)。線程才是CPU時間的分配對象。(6)系統(tǒng)調(diào)用CRuntime函數(shù)庫的Startupcode。(7)Startupcode調(diào)用app程序的WinMain函數(shù)。(8)app程序開始運(yùn)行。(5)系統(tǒng)為此進(jìn)程建立一個線程,稱為主線程(primary20(9)操作者關(guān)閉app主窗口,使WinMain中的消息循環(huán)結(jié)束,于是WinMain結(jié)束。(10)回到Startupcode。(11)回到系統(tǒng),系統(tǒng)調(diào)用ExitProcess結(jié)束進(jìn)程。(9)操作者關(guān)閉app主窗口,使WinMain中的消息循環(huán)結(jié)21因此通過這種方式執(zhí)行的所有Windows程序,都是shell的子進(jìn)程。但shell在調(diào)用CreateProcess時已經(jīng)剪斷了父進(jìn)程與子進(jìn)程之間的關(guān)系,而使它們成為獨(dú)立個體。可以寫一個程序,專門用來激活其它的程序。關(guān)鍵在于我們能否正確運(yùn)用具有眾多參數(shù)的API函數(shù)CreateProcess(圖3)因此通過這種方式執(zhí)行的所有Windows程序22如果一個進(jìn)程要結(jié)束自己,只要調(diào)用:VOIDExitProcess(UINTfuExitCode)如果說一個進(jìn)程要結(jié)束另一個進(jìn)程,可以使用:(圖4)顯然,只要有某個進(jìn)程的handle,就可以結(jié)束它。如果一個進(jìn)程要結(jié)束自己,只要調(diào)用:VOID23前面曾提過剪斷父子進(jìn)程關(guān)系的概念,只要我們在父進(jìn)程結(jié)束前,把它所開啟的核心對象(如子進(jìn)程、線程對象等)用CloseHandle關(guān)閉,就可以實(shí)現(xiàn)此目的,操作系統(tǒng)會自動把對象的計(jì)數(shù)值減1,表示與此核心對象不再有任何關(guān)系(圖5)。如果計(jì)數(shù)值為0,對象會自動被操作系統(tǒng)摧毀。前面曾提過剪斷父子進(jìn)程關(guān)系的概念,只要我們在243、一個線程的產(chǎn)生與死亡執(zhí)行程序代碼是線程的工作。當(dāng)一個進(jìn)程建立后,主線程也產(chǎn)生了。所以每一個Windows程序一開始就有一個線程。我們可以調(diào)用CreateThread產(chǎn)生額外的線程,系統(tǒng)會幫我們完成下列事情:(1)配置線程對象,其handle將成為CreateThread的返回值。3、一個線程的產(chǎn)生與死亡執(zhí)行程序代碼是線程的25(2)設(shè)定計(jì)數(shù)值為1。(3)配置線程的context。(4)保存線程的堆棧。(5)將context中的堆棧指針和指令指針設(shè)定妥當(dāng)。如果要在程序中產(chǎn)生一個新線程,調(diào)用CreateThread(圖6)即可。(例1、例2、例3)(2)設(shè)定計(jì)數(shù)值為1。(3)配置線程的context。(4)26當(dāng)完成工作后,應(yīng)該調(diào)用CloseHandle釋放核心對象(圖7)。(例4)使用“線程核心對象”的線程會使核心對象開啟。因此線程對象的默認(rèn)計(jì)數(shù)值為2。當(dāng)調(diào)用CloseHandle()時,計(jì)數(shù)值減1;當(dāng)線程對象結(jié)束時,計(jì)數(shù)值再減1。只有當(dāng)這兩件事都有發(fā)生了,對象才會被真正清除。當(dāng)完成工作后,應(yīng)該調(diào)用CloseHandle27線程的結(jié)束有兩種情況:(1)一種是正常結(jié)束這種情況是線程函數(shù)結(jié)束退出,線程也就自然結(jié)束了(例5

)。這時系統(tǒng)會調(diào)用ExitThread(圖8)做些清理工作;當(dāng)然線程自己也可以自行調(diào)用此函數(shù)來結(jié)束自己。(例6)線程的結(jié)束有兩種情況:(1)一種是正常結(jié)束這28在下面的程序中將CloseHandle函數(shù)與GetExitCodeThread函數(shù)的關(guān)系作了調(diào)整:CloseHandle的調(diào)用操作被移到了GetExitCodeThread的前面,目的是使GetExitCodeThread的調(diào)用失?。ɡ?)。在下面的程序中將CloseHandle函數(shù)與29前面使用了兩種等待方法。1)第一種方法是Win32Sleep()函數(shù)這個函數(shù)要求操作系統(tǒng)暫時中止線程的動作,直到經(jīng)過某個指定的時間后才能恢復(fù)。實(shí)際上,程序員不可能知道具體應(yīng)該要等待多少時間。2)第二種方法是使用循環(huán)等待,不斷調(diào)用GetExitCodeThread(),直到其結(jié)果不再是STILL_ACTIVE。前面使用了兩種等待方法。1)第一種方法是Win32Slee30這種方法對系統(tǒng)效率會造成沖擊。因此,絕對不要在Win32中使用這種循環(huán)的方法。(例8)3)Win32提供一種等待一個對象的方法:WaitForSingleObject()函數(shù)(圖9)(例9)4)Win32也提供一種同時等待一個以上對象的函數(shù)WaitForMultiplebject()(圖10)(例10)這種方法對系統(tǒng)效率會造成沖擊。因此,絕對不要31(2)非正常結(jié)束一是進(jìn)程結(jié)束(自然也導(dǎo)致線程的結(jié)束)。二是另外的線程以TerminateThread將它強(qiáng)制結(jié)束。不過TerminateThread少用為好。4、線程的種類MFC將線程分為工作者線程和用戶界面線程。(2)非正常結(jié)束一是進(jìn)程結(jié)束(自然也導(dǎo)致線程32(1)工作者線程(WorkerThreads)工作者線程與用戶界面無關(guān),沒有消息循環(huán),一般用來完成后臺工作。(2)用戶界面線程(UIThreads)用戶界面線程與用戶界面有關(guān),具有消息循環(huán)來處理界面消息,可與用戶進(jìn)行交互。(1)工作者線程(WorkerThreads)33五、MFC多線程程序設(shè)計(jì)1、產(chǎn)生一個工作者線程由于工作者線程與用戶界面無關(guān)。編程時,應(yīng)該準(zhǔn)備一個線程函數(shù),然后調(diào)用AfxBeginThread全局函數(shù):(圖11)(例11、例12、例13)2、產(chǎn)生一個用戶界面線程五、MFC多線程程序設(shè)計(jì)1、產(chǎn)生一個工作者線程34用戶界面線程不能只用一個線程函數(shù)來代表,因?yàn)樗幚硐⒀h(huán)。CWinThread::Run()成員函數(shù)中就有一個消息循環(huán)。所以應(yīng)該先從CWinThread類中派生一個自己的類,再調(diào)用全局函數(shù)AfxBeginThread產(chǎn)生一個CWinThread類的對象:(圖12)用戶界面線程不能只用一個線程函數(shù)來代表,因?yàn)?53、線程的結(jié)束工作者線程的生命就是線程函數(shù)本身,函數(shù)一旦return,線程也就結(jié)束。或者線程函數(shù)也可以調(diào)用AfxEndThread,結(jié)束線程。用戶界面線程因?yàn)橛邢⒀h(huán),必須在消息隊(duì)列中放一個WM_QUIT,才能結(jié)束線程。3、線程的結(jié)束工作者線程的生命就是線程函數(shù)本36放置消息WM_QUIT的方式和一般的Win32程序一樣,調(diào)用PostQuitMessage即可辦到;或者在線程的任何一個函數(shù)中調(diào)用AfxEndThread,也可以結(jié)束線程。放置消息WM_QUIT的方式和一般的Win337軟件工具與環(huán)境第二章多任務(wù)與多線程編程軟件工具與環(huán)境第二章38一、Windows程序的生與死在了解Windows程序的架構(gòu)以及它與Windows系統(tǒng)之間的關(guān)系后,對Windows消息種類以及產(chǎn)生時機(jī)的透徹了解,正是程序設(shè)計(jì)的關(guān)鍵。下面以窗口的產(chǎn)生與死亡,說明消息的產(chǎn)生與傳遞,以及應(yīng)用程序的生與死。一、Windows程序的生與死在了解Wind391、程序初始化過程中調(diào)用CreateWindow,為程序建立了一個窗口,作為程序的屏幕舞臺。CreateWindow產(chǎn)生窗口之后會送出WM_CREATE直接給窗口函數(shù),后者于是可以在此時做些初始化操作(例如配置內(nèi)存、打開文件、讀初始數(shù)據(jù)等。1、程序初始化過程中調(diào)用CreateWindow,為程序建立402、在程序活著的過程中,不斷以GetMessage從消息隊(duì)列中獲取消息。如果這個消息是WM_QUIT,GetMessage會返回0而結(jié)束while循環(huán),進(jìn)而結(jié)束整個程序。3、DispatchMessage通過WindowsUSER模塊的協(xié)助和監(jiān)督,把消息分發(fā)給窗口函數(shù)。消息將在該處被判別并處理。2、在程序活著的過程中,不斷以GetMessage從消息隊(duì)列414、程序不斷進(jìn)行上述2和3的操作。5、當(dāng)操作者按下系統(tǒng)菜單中的Close命令項(xiàng)時,系統(tǒng)送出WM_CLOSE。通常程序的窗口函數(shù)不攔截此消息,于是DefWindowProc處理它。6、DefWindowProc收到WM_CLOSE后調(diào)用DestroyWindow把窗口清除。DefWindowProc本身又會送出WM_DESTROY。4、程序不斷進(jìn)行上述2和3的操作。5、當(dāng)操作者按下系統(tǒng)菜單中427、程序?qū)W_DESTROY的標(biāo)準(zhǔn)反應(yīng)是調(diào)用PostQuitMessage。8、PostQuitMessage沒有什么操作,只送出WM_QUIT消息,準(zhǔn)備讓消息循環(huán)中的GetMessage獲取此消息,結(jié)束消息循環(huán)。7、程序?qū)W_DESTROY的標(biāo)準(zhǔn)反應(yīng)是調(diào)用PostQui43二、空閑時間的處理1、空閑時間的概念所謂空閑時間(idletime)是指“系統(tǒng)中沒有任何消息等待處理”的時間。例如沒有任何程序使用定時器(timer,它會定時送來WM_TIMER),使用者也沒有按鍵盤和鼠標(biāo)或操作任何外設(shè),那么系統(tǒng)就處于所謂的空閑時間。二、空閑時間的處理1、空閑時間的概念所謂空閑442、空閑時間的處理空閑時間經(jīng)常發(fā)生。后臺工作最適合在空閑時間完成。傳統(tǒng)的SDK程序如果要處理空閑時間,可以用下列循環(huán)取代WinMain中的傳統(tǒng)消息循環(huán)(見圖1)2、空閑時間的處理空閑時間經(jīng)常發(fā)生。后臺工作45原因是PeekMessage和GetMessage的性質(zhì)不同:它們都是從消息隊(duì)列中獲取消息,如果沒有消息,程序的主執(zhí)行線程(primarythread,是一個UI執(zhí)行線程)會被操作系統(tǒng)掛起。當(dāng)操作系統(tǒng)再次回來照顧這一執(zhí)行線程時,發(fā)現(xiàn)消息隊(duì)列中仍然是空的,這時兩個函數(shù)的行為就不同了:原因是PeekMessage和GetMess46(1)GetMessage會過門不入,于是操作系統(tǒng)再去照顧其它程序。(2)PeekMessage會取回控制權(quán),使程序得以執(zhí)行一段時間。于是上述消息循環(huán)進(jìn)入OnIdle函數(shù)中。(1)GetMessage會過門不入,于是操作系統(tǒng)再去照顧其47三、Windows的多任務(wù)1、Windows3.X的協(xié)同式多任務(wù)

Windows3.X都允許同時執(zhí)行多個程序。但分享CPU是程序的責(zé)任(即應(yīng)用程序具有對CPU的控制權(quán))。如果有一個程序不放棄CPU(許多程序采用傳統(tǒng)的消息循環(huán),而拒絕與其它程序共享資源),其它程序只有掛起而無法響應(yīng)操作。三、Windows的多任務(wù)1、Windows3.X的協(xié)同式482、Windows9X的搶先式多任務(wù)操作系統(tǒng)能夠強(qiáng)迫應(yīng)用程序把CPU分享給其它程序。即程序?qū)PU的占用時間由系統(tǒng)控制,系統(tǒng)為每個程序分配一定的CPU時間,當(dāng)程序的運(yùn)行超過規(guī)定時間后,系統(tǒng)就會中斷該程序并把CPU控制權(quán)讓給其它程序。2、Windows9X的搶先式多任務(wù)操作系統(tǒng)493、多線程多任務(wù)在Win32系統(tǒng)中,執(zhí)行一個程序,必然會產(chǎn)生一個進(jìn)程;當(dāng)一個進(jìn)程建立后,主線程也產(chǎn)生了。多任務(wù)是指系統(tǒng)可以同時運(yùn)行多個進(jìn)程,而每個進(jìn)程也可同時執(zhí)行多個線程。一個程序可以運(yùn)行多個線程,每個線程獨(dú)立地執(zhí)行程序代碼中的一組語句。3、多線程多任務(wù)在Win32系統(tǒng)中,執(zhí)行一個50四、進(jìn)程與線程通常用進(jìn)程(process)表示一個執(zhí)行中的程序,并認(rèn)為它是CPU調(diào)度單位。事實(shí)上線程(thread)才是調(diào)度單位。進(jìn)程是應(yīng)用程序的運(yùn)行實(shí)例。每個進(jìn)程都有自己私有的虛擬地址空間。每個進(jìn)程都有一個主線程,但可以建立另外的線程。進(jìn)程中的線程是并行執(zhí)行的,各線程占用CPU的時間由系統(tǒng)決定。四、進(jìn)程與線程通常用進(jìn)程(process)表51線程是Windows9X/NT系統(tǒng)調(diào)度分配CPU時間的基本單位。進(jìn)程至少有一個線程,也可以另外增加線程。系統(tǒng)為每個線程分配一個CPU時間片(約20ms),系統(tǒng)不停地在各個線程之間切換。線程只有在分配的時間片內(nèi)才有對CPU的控制權(quán)線程是Windows9X/NT系統(tǒng)調(diào)度分配C521、核心對象核心對象是系統(tǒng)的一種資源,系統(tǒng)對象一但產(chǎn)生,任何應(yīng)用程序都可以開啟并使用該對象。系統(tǒng)給予核心對象一個計(jì)數(shù)值作為管理之用。核心對象包括下列幾種:(見圖2)1、核心對象核心對象是系統(tǒng)的一種資源,系統(tǒng)對53這些核心對象的產(chǎn)生方式(使用的API)不同,但都會獲得一個handle作為識別;每被使用一次,其對應(yīng)的計(jì)數(shù)值就增1。核心對象的結(jié)束方式相當(dāng)一致,調(diào)用CloseHandle即可。Process對象不是用來執(zhí)行程序代碼的;它只是一個數(shù)據(jù)結(jié)構(gòu),系統(tǒng)用它來管理進(jìn)程。程序代碼的執(zhí)行是線程的工作。這些核心對象的產(chǎn)生方式(使用的API)不同,542、進(jìn)程的產(chǎn)生和死亡執(zhí)行一個程序,必然會產(chǎn)生一個進(jìn)程(process)。最直接的程序執(zhí)行方式就是在shell(如Windows9X的資源管理器)中用鼠標(biāo)雙擊某一個可執(zhí)行文件圖標(biāo)(如為app.exe),運(yùn)行起來的app進(jìn)程其實(shí)就是shell調(diào)用CreateProcess激活的。整個執(zhí)行流程如下:2、進(jìn)程的產(chǎn)生和死亡執(zhí)行一個程序,必然會產(chǎn)生55(1)shell調(diào)用CreateProcess激活app.exe(2)系統(tǒng)產(chǎn)生一個進(jìn)程核心對象,計(jì)數(shù)值為1。(3)系統(tǒng)為此進(jìn)程建立一個4GB地址空間。(4)加載器將必要的碼加載到上述地址空間中,包括app.exe的程序、數(shù)據(jù),以及所需的動態(tài)鏈接庫(dlls).(1)shell調(diào)用CreateProcess激活app.e56(5)系統(tǒng)為此進(jìn)程建立一個線程,稱為主線程(primarythread)。線程才是CPU時間的分配對象。(6)系統(tǒng)調(diào)用CRuntime函數(shù)庫的Startupcode。(7)Startupcode調(diào)用app程序的WinMain函數(shù)。(8)app程序開始運(yùn)行。(5)系統(tǒng)為此進(jìn)程建立一個線程,稱為主線程(primary57(9)操作者關(guān)閉app主窗口,使WinMain中的消息循環(huán)結(jié)束,于是WinMain結(jié)束。(10)回到Startupcode。(11)回到系統(tǒng),系統(tǒng)調(diào)用ExitProcess結(jié)束進(jìn)程。(9)操作者關(guān)閉app主窗口,使WinMain中的消息循環(huán)結(jié)58因此通過這種方式執(zhí)行的所有Windows程序,都是shell的子進(jìn)程。但shell在調(diào)用CreateProcess時已經(jīng)剪斷了父進(jìn)程與子進(jìn)程之間的關(guān)系,而使它們成為獨(dú)立個體??梢詫懸粋€程序,專門用來激活其它的程序。關(guān)鍵在于我們能否正確運(yùn)用具有眾多參數(shù)的API函數(shù)CreateProcess(圖3)因此通過這種方式執(zhí)行的所有Windows程序59如果一個進(jìn)程要結(jié)束自己,只要調(diào)用:VOIDExitProcess(UINTfuExitCode)如果說一個進(jìn)程要結(jié)束另一個進(jìn)程,可以使用:(圖4)顯然,只要有某個進(jìn)程的handle,就可以結(jié)束它。如果一個進(jìn)程要結(jié)束自己,只要調(diào)用:VOID60前面曾提過剪斷父子進(jìn)程關(guān)系的概念,只要我們在父進(jìn)程結(jié)束前,把它所開啟的核心對象(如子進(jìn)程、線程對象等)用CloseHandle關(guān)閉,就可以實(shí)現(xiàn)此目的,操作系統(tǒng)會自動把對象的計(jì)數(shù)值減1,表示與此核心對象不再有任何關(guān)系(圖5)。如果計(jì)數(shù)值為0,對象會自動被操作系統(tǒng)摧毀。前面曾提過剪斷父子進(jìn)程關(guān)系的概念,只要我們在613、一個線程的產(chǎn)生與死亡執(zhí)行程序代碼是線程的工作。當(dāng)一個進(jìn)程建立后,主線程也產(chǎn)生了。所以每一個Windows程序一開始就有一個線程。我們可以調(diào)用CreateThread產(chǎn)生額外的線程,系統(tǒng)會幫我們完成下列事情:(1)配置線程對象,其handle將成為CreateThread的返回值。3、一個線程的產(chǎn)生與死亡執(zhí)行程序代碼是線程的62(2)設(shè)定計(jì)數(shù)值為1。(3)配置線程的context。(4)保存線程的堆棧。(5)將context中的堆棧指針和指令指針設(shè)定妥當(dāng)。如果要在程序中產(chǎn)生一個新線程,調(diào)用CreateThread(圖6)即可。(例1、例2、例3)(2)設(shè)定計(jì)數(shù)值為1。(3)配置線程的context。(4)63當(dāng)完成工作后,應(yīng)該調(diào)用CloseHandle釋放核心對象(圖7)。(例4)使用“線程核心對象”的線程會使核心對象開啟。因此線程對象的默認(rèn)計(jì)數(shù)值為2。當(dāng)調(diào)用CloseHandle()時,計(jì)數(shù)值減1;當(dāng)線程對象結(jié)束時,計(jì)數(shù)值再減1。只有當(dāng)這兩件事都有發(fā)生了,對象才會被真正清除。當(dāng)完成工作后,應(yīng)該調(diào)用CloseHandle64線程的結(jié)束有兩種情況:(1)一種是正常結(jié)束這種情況是線程函數(shù)結(jié)束退出,線程也就自然結(jié)束了(例5

)。這時系統(tǒng)會調(diào)用ExitThread(圖8)做些清理工作;當(dāng)然線程自己也可以自行調(diào)用此函數(shù)來結(jié)束自己。(例6)線程的結(jié)束有兩種情況:(1)一種是正常結(jié)束這65在下面的程序中將CloseHandle函數(shù)與GetExitCodeThread函數(shù)的關(guān)系作了調(diào)整:CloseHandle的調(diào)用操作被移到了GetExitCodeThread的前面,目的是使GetExitCodeThread的調(diào)用失敗(例7)。在下面的程序中將CloseHandle函數(shù)與66前面使用了兩種等待方法。1)第一種方法是Win32Sleep()函數(shù)這個函數(shù)要求操作系統(tǒng)暫時中止線程的動作,直到經(jīng)過某個指定的時間后才能恢復(fù)。實(shí)際上,程序員不可能知道具體應(yīng)該要等待多少時間。2)第二種方法是使用循環(huán)等待,不斷調(diào)用GetExitCodeThre

溫馨提示

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

評論

0/150

提交評論