• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            C++ Programmer's Cookbook

            {C++ 基礎(chǔ)} {C++ 高級} {C#界面,C++核心算法} {設(shè)計(jì)模式} {C#基礎(chǔ)}

            windows核心編程--進(jìn)程

            進(jìn)程通常被定義為一個正在運(yùn)行的程序的實(shí)例,它由兩個部分組成:

            • 一個是操作系統(tǒng)用來管理進(jìn)程的內(nèi)核對象。內(nèi)核對象也是系統(tǒng)用來存放關(guān)于進(jìn)程的統(tǒng)計(jì)信息的地方。
            • 另一個是地址空間,它包含所有可執(zhí)行模塊或 D L L 模塊的代碼和數(shù)據(jù)。它還包含動態(tài)內(nèi)存分配的空間。如線程堆棧和堆分配空間。  

            進(jìn)程是不活潑的。若要使進(jìn)程完成某項(xiàng)操作,它必須擁有一個在它的環(huán)境中運(yùn)行的線程,該線程負(fù)責(zé)執(zhí)行包含在進(jìn)程的地址空間中的代碼。
            當(dāng)創(chuàng)建一個進(jìn)程時,系統(tǒng)會自動創(chuàng)建它的第一個線程,稱為主線程。然后,該線程可以創(chuàng)建其他的線程,而這些線程又能創(chuàng)建更多的線程。

            進(jìn)程的實(shí)例句柄  

            加載到進(jìn)程地址空間的每個可執(zhí)行文件或 D L L 文件均被賦予一個獨(dú)一無二的實(shí)例句柄。可執(zhí)行文件的實(shí)例作為 ( w ) Wi n M a i n 的第一個參數(shù) h i n s t E x e 來傳遞。對于加載資源的函數(shù)調(diào)用來說,通常都需要該句柄的值。例如,若要從可執(zhí)行文件的映象來加載圖標(biāo)資源,需要調(diào)用下面這個函數(shù):

            HICON LoadIcon( HINSTANCE hinst, PCTSTR pszIcon);

            L o a d I c o n 的第一個參數(shù)用于指明哪個文件(可執(zhí)行文件或 D L L 文件)包含你想加載的資源。

            注意 : 實(shí)際情況說明, H M O D U L E 與 H I N S TA N C E 是完全相同的對象。如果函數(shù)的文檔指明需要一個 H M O D U L E ,那么可以傳遞一個 H I N S TA N C E ,反過來,如果需要一個 H I N S TA N C E ,也可以傳遞一個 H M O D U L E 。之所以存在兩個數(shù)據(jù)類型,原因是在 1 6 位 Wi n d o w s 中, H M O D U L E 和 H I N S TA N C E 用于標(biāo)識不同的東西。

            G e t M o d u l e H a n d l e 函數(shù)返回可執(zhí)行文件或 D L L 文件加載到進(jìn)程的地址空間時所用的句柄 / 基地址:

            HMODULE GetModuleHandle( PCTSTR pszModule);

            當(dāng)調(diào)用該函數(shù)時,你傳遞一個以 0 結(jié)尾的字符串,用于設(shè)定加載到調(diào)用進(jìn)程的地址空間的可執(zhí)行文件或 D L L 文件的名字。如果系統(tǒng)找到了指定的可 執(zhí)行文件或 D L L 文件名, G e t M o d u l e H a n d l e 便返回該可執(zhí)行文件或 D L L 文件映象加載到的基地址。如果系統(tǒng)沒有找到該文件,則 返回 N U L L 。也可以調(diào)用 G e t M o d u l e H a n d l e ,為 p s z M o d u l e 參數(shù)傳遞 N U L L , G e t M o d u l e H a n d l e 返回調(diào) 用的可執(zhí)行文件的基地址。  

            進(jìn)程的命令行

            當(dāng)一個新進(jìn)程創(chuàng)建時,它要傳遞一個命令行。該命令行幾乎永遠(yuǎn)不會是空的,至少用于創(chuàng)建新進(jìn)程的可執(zhí)行文件的名字是命令行上的第一個標(biāo)記。當(dāng) C 運(yùn)行期的啟動代碼開始運(yùn)行的時候,它要檢索進(jìn)程的命令行,跳過可執(zhí)行文件的名字,并將指向命令行其余部分的指針傳遞給 Wi n M a i n 的 p s z C m d L i n e 參數(shù)。

            進(jìn)程的環(huán)境變量

            每個進(jìn)程都有一個與它相關(guān)的環(huán)境塊。環(huán)境塊是進(jìn)程的地址空間中分配的一個內(nèi)存塊。每個環(huán)境塊都包含一組字符串,其形式如下:

            VarName1=VarValue1\0

            VarName2=VarValue2\0

            VarName3=VarValue3\0

            ...

            VarNameX=VarValueX\0

            \0

            每個字符串的第一部分是環(huán)境變量的名字,后跟一個等號,等號后面是要賦予變量的值。

            DWORD GetEnvironmentVariable(

               PCTSTR pszName,

               PTSTR pszValue,

               DWORD cchValue);

            當(dāng)調(diào)用 G e t E n v i r o n m e n t Va r i a b l e 時, p s z N a m e 指向需要的變量名, p s z Va l u e 指向用于存放變量值的緩存, c c h Va l u e 用于指明緩存的大小(用字符數(shù)來表示)。該函數(shù)可以返回拷貝到緩存的字符數(shù),如果在環(huán)境中找不到該變量名,也可以返回 0 。

            BOOL SetEnvironmentVariable(

               PCTSTR pszName,

               PCTSTR pszValue);

            該函數(shù)用于將 p s z N a m e 參數(shù)標(biāo)識的變量設(shè)置為 p s z Va l u e 參數(shù)標(biāo)識的值。如果帶有指定名字的變量已經(jīng)存在, S e t E n v i r o n m e n t Va r i a b l e 就修改該值。如果指定的變量不存在,便添加該變量,如果 p s z Va l u e 是 N U L L ,便從環(huán)境塊中刪除該變量。

            進(jìn)程的親緣性

            一般來說,進(jìn)程中的線程可以在主計(jì)算機(jī)中的任何一個 C P U 上執(zhí)行。但是一個進(jìn)程的線程可能被強(qiáng)制在可用 C P U 的子集上運(yùn)行。這稱為進(jìn)程的親緣性,

            進(jìn)程的錯誤模式

            進(jìn)程可以告訴系統(tǒng)如何處理每一種錯誤。方法是調(diào)用 S e t E r r o r M o d e 函數(shù):

            UINT SetErrorMode(UINT fuErrorMode);

            f u E r r o r M o d e 參數(shù)是表 4 - 3 的任何標(biāo)志按位用 O R 連接在一起的組合。

            表4-3 fuError Mode 參數(shù)的標(biāo)志

            標(biāo)志
             說明
             
            SEM_FAILCRITICALERRORS
             系統(tǒng)不顯示關(guān)鍵錯誤句柄消息框,并將錯誤返回給調(diào)用進(jìn)程
             
            SEM_NOGOFAULTERRORBOX
             系統(tǒng)不顯示一般保護(hù)故障消息框。本標(biāo)志只應(yīng)該由采用異常情況處理程序來處理一般保護(hù)(G P)故障的調(diào)試應(yīng)用程序來設(shè)定
             
            SEM_NOOPENFILEERRORBOX
             當(dāng)系統(tǒng)找不到文件時,它不顯示消息框
             
            SEM_NOALIGNMENTFAULTEXCEPT
             系統(tǒng)自動排除內(nèi)存沒有對齊的故障,并使應(yīng)用程序看不到這些故障。本標(biāo)志對x 8 6處理器不起作用
             

            進(jìn)程的當(dāng)前驅(qū)動器和目錄

            通過調(diào)用下面兩個函數(shù),線程能夠獲得和設(shè)置它的進(jìn)程的當(dāng)前驅(qū)動器和目錄:
              
            DWORD GetCurrentDirectory(
               DWORD cchCurDir,
               PTSTR pszCurDir);
            BOOL SetCurrentDirectory(PCTSTR pszCurDir);
            CreateProcess 函數(shù)

            可以用 C r e a t e P r o c e s s 函數(shù)創(chuàng)建一個進(jìn)程:

            BOOL CreateProcess(

               PCTSTR pszApplicationName,

               PTSTR pszCommandLine,

               PSECURITY_ATTRIBUTES psaProcess,

               PSECURITY_ATTRIBUTES psaThread,

               BOOL bInheritHandles,

               DWORD fdwCreate,

               PVOID pvEnvironment,

               PCTSTR pszCurDir,

               PSTARTUPINFO psiStartInfo,

               PPROCESS_INFORMATION ppiProcInfo);

            當(dāng)一個線程調(diào)用 CreateProcess 時,系統(tǒng)就會創(chuàng)建一個進(jìn)程內(nèi)核對象,其初始使用計(jì)數(shù)是 1 。

            當(dāng)?shù)谝粋€參數(shù)為 NULL 時 , C r e a t e P r o c e s s 也按下面的順序搜索該可執(zhí)行文件:

            1) 包含調(diào)用進(jìn)程的 . e x e 文件的目錄。

            2) 調(diào)用進(jìn)程的當(dāng)前目錄。

            3) Wi n d o w s 的系統(tǒng)目錄。

            4) Wi n d o w s 目錄。

            5) PAT H 環(huán)境變量中列出的目錄。

            當(dāng)然,如果文件名包含全路徑,系統(tǒng)將使用全路徑來查看可執(zhí)行文件,并且不再搜索這些目錄。如果系統(tǒng)找到了可執(zhí)行文件,那么它就創(chuàng)建一個新進(jìn)程,并將可執(zhí)行文件的代碼和數(shù)據(jù)映射到新進(jìn)程的地址空間中。然后系統(tǒng)將調(diào)用 C / C + + 運(yùn)行期啟動例程。正如前面我們講過的那樣, C / C + + 運(yùn)行期啟動例程要查看進(jìn)程的命令行,并將地址作為 ( w ) Wi n M a i n 的 p s z C m d L i n e 參數(shù)傳遞給可執(zhí)行文件的名字后面的第一個參數(shù)。

            終止進(jìn)程的運(yùn)行

            若要終止進(jìn)程的運(yùn)行,可以使用下面四種方法:  

            • 主線程的進(jìn)入點(diǎn)函數(shù)返回(最好使用這個方法)。  

            • 進(jìn)程中的一個線程調(diào)用 E x i t P r o c e s s 函數(shù)(應(yīng)該避免使用這種方法)。  

            • 另一個進(jìn)程中的線程調(diào)用 Te r m i n a t e P r o c e s s 函數(shù)(應(yīng)該避免使用這種方法)。  

            • 進(jìn)程中的所有線程自行終止運(yùn)行(這種情況幾乎從未發(fā)生)。  

            主線程的進(jìn)入點(diǎn)函數(shù)返回

            始終都應(yīng)該這樣來設(shè)計(jì)應(yīng)用程序,即只有當(dāng)主線程的進(jìn)入點(diǎn)函數(shù)返回時,它的進(jìn)程才終止運(yùn)行。這是保證所有線程資源能夠得到正確清除的唯一辦法。讓主線程的進(jìn)入點(diǎn)函數(shù)返回,可以確保下列操作的實(shí)現(xiàn):

            • 該線程創(chuàng)建的任何 C + + 對象將能使用它們的析構(gòu)函數(shù)正確地撤消。  

            • 操作系統(tǒng)將能正確地釋放該線程的堆棧使用的內(nèi)存。  

            • 系統(tǒng)將進(jìn)程的退出代碼(在進(jìn)程的內(nèi)核對象中維護(hù))設(shè)置為進(jìn)入點(diǎn)函數(shù)的返回值。  

            • 系統(tǒng)將進(jìn)程內(nèi)核對象的返回值遞減 1 。

            ExitProcess 函數(shù)

            當(dāng)進(jìn)程中的一個線程調(diào)用 E x i t P r o c e s s 函數(shù)時,進(jìn)程便終止運(yùn)行:
                
            VOID ExitProcess(UINT fuExitCode);    
              
            當(dāng)主線程的進(jìn)入點(diǎn)函數(shù)( WinMain 、 wWinMain 、 main 或 wmain )返回時,它將返回給 C / C + + 運(yùn)行期啟動代碼,它能正確地清除該進(jìn)程使用的所有的 C 運(yùn)行期資源。當(dāng) C 運(yùn)行期資源被釋放之后, C 運(yùn)行期啟動代碼就顯式調(diào)用 E x i t P r o c e s s ,并將進(jìn)入點(diǎn)函數(shù)返回的值傳遞給它。這解釋了為什么只需要主線程的進(jìn)入點(diǎn)函數(shù)返回,就能夠終止整個進(jìn)程的運(yùn)行。請注意,進(jìn)程中運(yùn)行的任何其他線程都隨著進(jìn)程而一道終止運(yùn)行。

            注意,調(diào)用 E x i t P r o c e s s 或 E x i t T h r e a d 可使進(jìn)程或線程在函數(shù)中就終止運(yùn)行。就操作系統(tǒng)而言,這很好,進(jìn)程或線程的所有操作系統(tǒng)資源都將被全部清除。但是, C / C + + 應(yīng)用程序應(yīng)該避免調(diào)用這些函數(shù),因?yàn)?C / C + + 運(yùn)行期也許無法正確地清除。

            TerminateProcess 函數(shù)

            調(diào)用 Te r m i n a t e P r o c e s s 函數(shù)也能夠終止進(jìn)程的運(yùn)行:

            BOOL TerminateProcess(HANDLE hProcess, UINT fuExitCode);

            該函數(shù)與 E x i t P r o c e s s 有一個很大的差別,那就是任何線程都可以調(diào)用 Te r m i n a t e P r o c e s s 來終止另一個進(jìn)程或它自己的進(jìn)程的運(yùn)行。 h P r o c e s s 參數(shù)用于標(biāo)識要終止運(yùn)行的進(jìn)程的句柄。

            只有當(dāng)無法用另一種方法來迫使進(jìn)程退出時,才應(yīng)該使用 Te r m i n a t e P r o c e s s 。終止運(yùn)行的進(jìn)程絕對得不到關(guān)于它將終止運(yùn)行的任何通知,因?yàn)閼?yīng)用程序無法正確地清除,并且不能避免自己被撤消(除非通過正常的安全機(jī)制)。

            進(jìn)程終止運(yùn)行時出現(xiàn)的情況

            當(dāng)進(jìn)程終止運(yùn)行時,下列操作將啟動運(yùn)行:  

            1) 進(jìn)程中剩余的所有線程全部終止運(yùn)行。  

            2) 進(jìn)程指定的所有用戶對象和 G D I 對象均被釋放,所有內(nèi)核對象均被關(guān)閉(如果沒有其他 進(jìn)程打開它們的句柄,那么這些內(nèi)核對象將被撤消。但是,如果其他進(jìn)程打開了它們的句柄, 內(nèi)核對象將不會撤消)。  

            3) 進(jìn)程的退出代碼將從 S T I L L _ A C T I V E 改為傳遞給 E x i t P r o c e s s 或 Te r m i n a t e P r o c e s s 的代碼。  

            4) 進(jìn)程內(nèi)核對象的狀態(tài)變成收到通知的狀態(tài)(關(guān)于傳送通知的詳細(xì)說明,參見第 9 章)。系 統(tǒng)中的其他線程可以掛起,直到進(jìn)程終止運(yùn)行。  

            5) 進(jìn)程內(nèi)核對象的使用計(jì)數(shù)遞減 1 。

            注意,進(jìn)程的內(nèi)核對象的壽命至少可以達(dá)到進(jìn)程本身那么長,但是進(jìn)程內(nèi)核對象的壽命可能大大超過它的進(jìn)程壽命。當(dāng)進(jìn)程終止運(yùn)行時,系統(tǒng)能夠自動確定它的內(nèi)核對象的使用計(jì)數(shù)。如果使用計(jì)數(shù)降為 0 ,那么沒有其他進(jìn)程擁有該對象打開的句柄,當(dāng)進(jìn)程被撤消時,對象也被撤消。

            子進(jìn)程

            子進(jìn)程 , 能夠處理比線程更復(fù)雜的東西 , 也能夠保持相對的獨(dú)立 , 但是就會有進(jìn)程間的數(shù)據(jù)共享 , Wi n d o w s 提供了若干種方法,以便在不同的進(jìn)程中間傳送數(shù)據(jù),比如動態(tài)數(shù)據(jù)交換( D D E )、 O L E 、管道和郵箱等。共享數(shù)據(jù)最方便的方法之一是,使用內(nèi)存映射文件 . 大多數(shù)情況下,應(yīng)用程序?qū)⒘硪粋€進(jìn)程作為獨(dú)立的進(jìn)程來啟動。這意味著進(jìn)程創(chuàng)建和開始運(yùn)行后,父進(jìn)程并不需要與新進(jìn)程進(jìn)行通信,也不需要在完成它的工作后父進(jìn)程才能繼續(xù)運(yùn)行。這就是 E x p l o r e r 的運(yùn)行方式。當(dāng) E x p l o r e r 為用戶創(chuàng)建一個新進(jìn)程后,它并不關(guān)心該進(jìn)程是否繼續(xù)運(yùn)行,也不在乎用戶是否終止它的運(yùn)行。

            若要放棄與子進(jìn)程的所有聯(lián)系, E x p l o r e r 必須通過調(diào)用 C l o s e H a n d l e 來關(guān)閉它與新進(jìn)程及它的主線程之間的句柄。下面的代碼示例顯示了如何創(chuàng)建新進(jìn)程以及如何讓它以獨(dú)立方式來運(yùn)行:


            PROCESS_INFORMATION pi;
            //Spawn the child process.
            BOOL fSuccess = CreateProcess(..., π);
            if(fSuccess)
            {
               //Allow the system to destroy the process & thread kernel
               //objects as soon as the child process terminates.
               CloseHandle(pi.hThread);
               CloseHandle(pi.hProcess);
            }

            posted on 2006-09-12 14:38 夢在天涯 閱讀(1950) 評論(0)  編輯 收藏 引用 所屬分類: Windows API

            公告

            EMail:itech001#126.com

            導(dǎo)航

            統(tǒng)計(jì)

            • 隨筆 - 461
            • 文章 - 4
            • 評論 - 746
            • 引用 - 0

            常用鏈接

            隨筆分類

            隨筆檔案

            收藏夾

            Blogs

            c#(csharp)

            C++(cpp)

            Enlish

            Forums(bbs)

            My self

            Often go

            Useful Webs

            Xml/Uml/html

            搜索

            •  

            積分與排名

            • 積分 - 1807503
            • 排名 - 5

            最新評論

            閱讀排行榜

            日韩乱码人妻无码中文字幕久久 | 久久综合狠狠综合久久97色| 亚洲国产精品久久久久久| 久久综合久久综合久久| 久久无码精品一区二区三区| 久久亚洲国产精品123区| 久久精品免费全国观看国产| 久久久久99精品成人片试看| 国产视频久久| 久久精品亚洲日本波多野结衣| 国产真实乱对白精彩久久| 热99RE久久精品这里都是精品免费| 国产婷婷成人久久Av免费高清| 久久精品国产99国产精品| 人妻无码久久一区二区三区免费 | 中文无码久久精品| 成人国内精品久久久久影院VR| 亚洲日韩中文无码久久| 国产L精品国产亚洲区久久| 亚洲国产精品无码久久久秋霞2 | 国产精品久久久久一区二区三区 | 日韩AV无码久久一区二区| 国产激情久久久久影院老熟女免费 | 久久精品视频一| 国产成人久久精品麻豆一区| 新狼窝色AV性久久久久久| 久久久久久久综合综合狠狠| 国产午夜精品理论片久久影视| 久久精品国产亚洲AV影院| 久久久精品国产亚洲成人满18免费网站| 亚洲欧洲日产国码无码久久99| 久久久久综合中文字幕| 久久精品国产精品亚洲精品| 久久亚洲精品国产精品| 一本色道久久99一综合| 欧美亚洲国产精品久久| 思思久久99热只有频精品66| 欧美伊人久久大香线蕉综合 | 久久久久国产日韩精品网站| 99久久精品免费看国产一区二区三区| 国产精品久久久久久久久鸭|