qileilove

          blog已經(jīng)轉(zhuǎn)移至github,大家請(qǐng)?jiān)L問(wèn) http://qaseven.github.io/

          Windows操作系統(tǒng)下創(chuàng)建進(jìn)程的過(guò)程

           進(jìn)程(Process)是具有一定獨(dú)立功能的程序關(guān)于某個(gè)數(shù)據(jù)集合上的一次運(yùn)行活動(dòng),是系統(tǒng)進(jìn)行資源分配和調(diào)度的一個(gè)獨(dú)立單位。程序只是一組指令的有序集合,它本身沒(méi)有任何運(yùn)行的含義,只是一個(gè)靜態(tài)實(shí)體。而進(jìn)程則不同,它是程序在某個(gè)數(shù)據(jù)集上的執(zhí)行,是一個(gè)動(dòng)態(tài)實(shí)體。它因創(chuàng)建而產(chǎn)生,因調(diào)度而運(yùn)行,因等待資源或事件而被處于等待狀態(tài),因完成任務(wù)而被撤消,反映了一個(gè)程序在一定的數(shù)據(jù)集上運(yùn)行的全部動(dòng)態(tài)過(guò)程。
            線程(Thread)是進(jìn)程的一個(gè)實(shí)體,是CPU調(diào)度和分派的基本單位。線程不能夠獨(dú)立執(zhí)行,必須依存在進(jìn)程中,由進(jìn)程提供多個(gè)線程執(zhí)行控制。從內(nèi)核角度講線程是活動(dòng)體對(duì)象,而進(jìn)程只是一組靜態(tài)的對(duì)象集,進(jìn)程必須至少擁有一個(gè)活動(dòng)線程才能維持運(yùn)轉(zhuǎn)。
            當(dāng)某個(gè)應(yīng)用程序調(diào)用一個(gè)創(chuàng)建進(jìn)程的函數(shù)比如CreateProcess或者用戶執(zhí)行某一個(gè)程序(其實(shí)windows下用戶執(zhí)行一般普通程序是由explorer.exe調(diào)用CreateProcess來(lái)完成),操作系統(tǒng)把這個(gè)過(guò)程分成以下步驟來(lái)完成:
            1.打開(kāi)將要在該進(jìn)程中執(zhí)行的映像文件。
            2.創(chuàng)建Windows執(zhí)行體進(jìn)程對(duì)象。
            3.創(chuàng)建初始線程(棧、堆執(zhí)行環(huán)境初始化及執(zhí)行線程體對(duì)象)。
            4.通知Windows子系統(tǒng)新進(jìn)程創(chuàng)建了(子系統(tǒng)是操作系統(tǒng)的一部分它是一個(gè)協(xié)助操作系統(tǒng)內(nèi)核管理用戶態(tài)/客戶方的一個(gè)子系統(tǒng)具體的進(jìn)程為Csrss.exe)。
            5.開(kāi)始執(zhí)行初始線程(如果創(chuàng)建時(shí)候指定了線程的CREATE_SUSPENDED狀態(tài)則線程暫時(shí)掛起不執(zhí)行)。
            6.在新進(jìn)程和線程環(huán)境中完成地址空間的初始化(比如加載必須的DLL和庫(kù)),然后開(kāi)始到進(jìn)程入口執(zhí)行。
            到這里操作系統(tǒng)完成一個(gè)新進(jìn)程的創(chuàng)建過(guò)程。下面來(lái)看下具體每一步操作系統(tǒng)所做的工作
            1.打開(kāi)將要在該進(jìn)程中執(zhí)行的映像文件。
            首先操作系統(tǒng)找到執(zhí)行的Windows映像然后創(chuàng)建一個(gè)內(nèi)存區(qū)對(duì)象,以便后面將它映射到新的進(jìn)程地址空間中。
            2.創(chuàng)建Windows執(zhí)行體進(jìn)程對(duì)象。
            接下來(lái)操作系統(tǒng)調(diào)用內(nèi)部的系統(tǒng)函數(shù)NtCreateProcess來(lái)創(chuàng)建一個(gè)Windwos執(zhí)行體進(jìn)程對(duì)象。具體步驟是:
            (1)建立EPROCESS
            *分配并初始化EPROCESS結(jié)構(gòu)塊
            *從父進(jìn)程處繼承得到進(jìn)程的親和性掩碼
            *分配進(jìn)程的最大最小工作集尺(由兩個(gè)參數(shù)決定PsMinimumWorkingSet PsMaximumWorkingSet)
            *降新進(jìn)程的配額塊設(shè)置為父進(jìn)程配額塊地址,并遞增父進(jìn)程配額塊的引用計(jì)數(shù)
            *繼承Windows的設(shè)備名字空間
            *將父進(jìn)程進(jìn)程ID保存在新進(jìn)程對(duì)象的InheritedFormUniqueProcessId中
            *創(chuàng)建該進(jìn)程的主訪問(wèn)令牌
            *初始化進(jìn)程句柄表
            *將新進(jìn)程的退出狀態(tài)設(shè)置為STATUS_PENDING
            (2)創(chuàng)建初始的進(jìn)程地址空間
            *在適當(dāng)?shù)捻?yè)表中創(chuàng)建頁(yè)表項(xiàng),以映射初始頁(yè)面
            *從MmresidentAvailablePage算出進(jìn)程工作集大小
            *系統(tǒng)空間的非換頁(yè)部分和系統(tǒng)緩存的頁(yè)表被映射到進(jìn)程
            (3)初始化內(nèi)核進(jìn)程塊KPROCESS
            (4)結(jié)束進(jìn)程地址空間的創(chuàng)建過(guò)程
            (5)建立PEB
            (6)完成執(zhí)行體進(jìn)程對(duì)象的創(chuàng)建過(guò)程
           3.創(chuàng)建初始線程(棧、堆執(zhí)行環(huán)境初始化及執(zhí)行線程體對(duì)象)。
            這時(shí)候Windows執(zhí)行體進(jìn)程對(duì)象已經(jīng)完全建立完成,但它還沒(méi)有線程所以無(wú)法執(zhí)行,接下來(lái)系統(tǒng)調(diào)用NtCreateThread來(lái)創(chuàng)建一個(gè)掛起的新線程它就是進(jìn)程的主線程體。
            4.通知Windows子系統(tǒng)新進(jìn)程創(chuàng)建了(子系統(tǒng)是操作系統(tǒng)的一部分它是一個(gè)協(xié)助操作系統(tǒng)內(nèi)核管理用戶態(tài)/客戶方的一個(gè)子系統(tǒng)具體的進(jìn)程為Csrss.exe)。接下來(lái)操作系統(tǒng)通過(guò)客戶態(tài)(Kernel32.dll)給Windows子系統(tǒng)(Csrss)發(fā)送一個(gè)新進(jìn)程線程創(chuàng)建的數(shù)據(jù)消息,讓子系統(tǒng)建立自己的進(jìn)程線程管理塊。當(dāng)Csrss接收到該消息時(shí)候執(zhí)行下面的處理:
            *復(fù)制一份該進(jìn)程和線程句柄
            *設(shè)置進(jìn)程優(yōu)先級(jí)
            *分配Csrss進(jìn)程塊
            *把新進(jìn)程的異常處理端口綁定到Csrss中,這樣當(dāng)該進(jìn)程發(fā)生異常時(shí),Csrss將會(huì)接收到異常消息
            *分配和初始化Csrss線程塊
            *把線程插入到進(jìn)程的線程列表中
            *把進(jìn)程插入到Csrss的線程列表中
            *顯示進(jìn)程啟動(dòng)光標(biāo)
            5.開(kāi)始執(zhí)行初始線程(如果創(chuàng)建時(shí)候指定了線程的CREATE_SUSPENDED狀態(tài)則線程暫時(shí)掛起不執(zhí)行)。到這里進(jìn)程環(huán)境已經(jīng)建立完畢進(jìn)程中開(kāi)始創(chuàng)建的主線程到這里獲得執(zhí)行權(quán)開(kāi)始執(zhí)行線程。
            6.在新進(jìn)程和線程環(huán)境中完成地址空間的初始化(比如加載必須的DLL和庫(kù)),然后開(kāi)始到進(jìn)程入口執(zhí)行。
            到這步實(shí)質(zhì)是調(diào)用ldrInitializeThunk來(lái)初始化加載器,堆管理器NLS表TLS數(shù)組以及臨界區(qū)結(jié)構(gòu),并且加載任何必須要的DLL并且用
            DLL_PROCESS_ATTACH功能代碼來(lái)調(diào)用各DLL入口點(diǎn),最后當(dāng)加載器初始化例程返回到用戶模式APC分發(fā)器時(shí)進(jìn)程映像開(kāi)始在用戶模式下執(zhí)行,然后它調(diào)用線程啟動(dòng)函數(shù)開(kāi)始執(zhí)行。
            到這里操作系統(tǒng)完成了所有的創(chuàng)建工作,我們寫(xiě)的程序就這樣被操作系統(tǒng)調(diào)用運(yùn)行起來(lái)了。

          posted on 2013-11-25 10:22 順其自然EVO 閱讀(238) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          <2013年11月>
          272829303112
          3456789
          10111213141516
          17181920212223
          24252627282930
          1234567

          導(dǎo)航

          統(tǒng)計(jì)

          常用鏈接

          留言簿(55)

          隨筆分類(lèi)

          隨筆檔案

          文章分類(lèi)

          文章檔案

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 邹城市| 屏山县| 南汇区| 类乌齐县| 迁安市| 蒙山县| 翁源县| 瓮安县| 佛学| 通许县| 新蔡县| 铜梁县| 福海县| 静宁县| 怀安县| 东城区| 阿勒泰市| 宣城市| 开化县| 新昌县| 太保市| 盐津县| 安吉县| 凤山市| 洪雅县| 永济市| 谢通门县| 高陵县| 武义县| 昌都县| 乌海市| 定边县| 普陀区| 吉隆县| 正定县| 洪湖市| 大新县| 云安县| 昌宁县| 白玉县| 千阳县|