實驗2.3.1_創(chuàng)建進程_第1頁
已閱讀1頁,還剩33頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

1、操作系統(tǒng)實驗 創(chuàng)建進程,,學會通過基本的Windows進程控制函數(shù),由父進程創(chuàng)建子進程。,實驗?zāi)康?我們設(shè)計一個應(yīng)用程序時,有時候需要另外一段代碼做一些其它工作。方法如下:一、函數(shù)調(diào)用或者子程序弊端:我們可以用函數(shù)調(diào)用或者子程序,但是我們調(diào)用函數(shù)之后,只能等函數(shù)返回;二、在進程內(nèi)創(chuàng)建一個新線程弊端:但是如果在一個復雜應(yīng)用系統(tǒng)中,我們有可能不慎改寫了進程地址空間中的某些數(shù)據(jù)(例如某些引用數(shù)據(jù)),導致其它工作不能正確地進行。,,三

2、、創(chuàng)建新進程(子進程)所以當我們需要某些工作同時進行,并且希望保護它們的運行地址空間時,一個很好地辦法是創(chuàng)建一個新進程來執(zhí)行需要同時進行的工作。,,假設(shè)現(xiàn)在有這樣的一個工作,需要計算1——100的和,還需要做一個工作是讀寫文件。我們可以讓父進程計算,創(chuàng)建一個子進程實現(xiàn)讀寫文件。主要工作:1、首先由父進程創(chuàng)建子進程2、讓子進程創(chuàng)建一個文件并寫入數(shù)據(jù),子進程寫文件過程中,父進程繼續(xù)執(zhí)行計算工作3、等子進程執(zhí)行完以后,父進程讀

3、取文件內(nèi)容輸出,實現(xiàn)進程協(xié)同工作。,實驗內(nèi)容,父進程框架void main(){//為創(chuàng)建進程做準備工作//創(chuàng)建子進程If(創(chuàng)建失敗)返回Else(創(chuàng)建成功)//執(zhí)行計算1——100的和//等子進程執(zhí)行完,讀取子進程的文件內(nèi)容,并輸出。},程序框架,子進程框架void main(){//創(chuàng)建文件If(失?。┓祷谽lse(成功)//向文件寫入數(shù)據(jù)//讀取文件內(nèi)容輸出},,BOOL CreateProc

4、ess( LPCTSTR lpApplicationName , //指定可執(zhí)行程序名LPTSTR lpCommandLine , //命令行字符串,可以為NULLLPSECURITY_ATTRIBUTES lpProcessAttributes , //新進程對象的安全屬性LPSECURITY_ATTRIBUTES lpThreadAttributes , //新進程對應(yīng)線程的安全屬性BOOL bInheritHandles

5、 ,//指定父進程的對象句柄是否能被子進程繼承DWORD dwCreationFlags , //指定創(chuàng)建進程的附加標記,即指定新創(chuàng)建進程的特性LPVOID lpEnvironment ,//指定新進程使用的環(huán)境,NULL表示同父進程環(huán)境LPCTSTR lpCurrentDirectory , //指定子進程當前路徑,NULL表示與父進程路徑相同LPSTARTUPINFO lpStartupInfo , //指定新進程主窗口如何

6、顯示LPPROCESS_INFORMATION lpProcessInformation //作為返回值使用,是一個指針);,父進程創(chuàng)建子進程用CreateProcess函數(shù)來創(chuàng)建一個新進程,當調(diào)用CreateProcess時,系統(tǒng)所做的工作:1、首先,系統(tǒng)創(chuàng)建一個進程內(nèi)核對象,其初始使用計數(shù)為1。(進程內(nèi)核對象并不代表進程本身,而是操作系統(tǒng)用來管理這個進程的一個數(shù)據(jù)結(jié)構(gòu)。),,2、然后,系統(tǒng)為新進程創(chuàng)建一個虛擬地址空間

7、,并將可執(zhí)行文件(和所有必要的DLL)的代碼及數(shù)據(jù)加載到進程的地址空間。3、最后,系統(tǒng)為新進程創(chuàng)建一個主線程內(nèi)核對象(使用計數(shù)為1)(線程內(nèi)核對象是操作系統(tǒng)用來管理線程的數(shù)據(jù)結(jié)構(gòu)。),,系統(tǒng)做完這些工作以后,新進程的主線程就開始執(zhí)行運行時的啟動代碼,在啟動代碼中會調(diào)用應(yīng)用程序的main函數(shù),這樣,新進程就從main函數(shù)開始執(zhí)行。如果調(diào)用CreateProcess函數(shù)后,系統(tǒng)成功創(chuàng)建了新進程并且創(chuàng)建了其主線程,則系統(tǒng)返回TRU

8、E,否則返回FALSE。,,討論CreateProcess的參數(shù)。LPCTSTR lpApplicationNamelpApplicationName參數(shù)指定新進程要使用的可執(zhí)行文件的名稱??梢允峭暾窂胶臀募?,也可以是部分名稱。注意一定要加上擴展名“.exe”。在本次實驗中,使用全路徑和文件名。CreateProcess("G:\\Projects\\操作系統(tǒng)編程實驗\\創(chuàng)建進程\\Child\\Debug\\C

9、hild.exe",NULL,…)(該參數(shù)可以為NULL,這時文件名必須是參數(shù)lpCommandLine 指向的字符串中第一個空格界定的標記。),,LPTSTR lpCommandLinelpCommandLine參數(shù)用來指定傳遞給新進程的命令行字符串。在本次實驗中,不需要這個參數(shù),可以設(shè)為NULL。(在很多時候,我們將可執(zhí)行文件名和命令行參數(shù)都傳給lpCommandLine參數(shù),CreateProcess函數(shù)分析

10、lpCommandLine參數(shù)時,會把該字符串中第一個空格分隔的標記作為可執(zhí)行文件名,如果是可執(zhí)行文件名是部分路徑,則函數(shù)會在系統(tǒng)目錄中按從下到上的順序搜索可執(zhí)行文件。),,LPSECURITY_ATTRIBUTES lpProcessAttributes 和 LPSECURITY_ATTRIBUTES lpThreadAttributes lpProcessAttributes和lpThreadAttributes 都是指向指向

11、LPSECURITY_ATTRIBUTES 結(jié)構(gòu)體的指針。前面介紹過,當調(diào)用CreateProcess函數(shù)創(chuàng)建新進程時,系統(tǒng)將為新進程創(chuàng)建一個進程內(nèi)核對象和一個主線程內(nèi)核對象。lpProcessAttributes和lpThreadAttributes 參數(shù)就是分別用來設(shè)置新進程內(nèi)核對象和主線程內(nèi)核對象的安全屬性。在本次實驗中為這兩參數(shù)傳遞NULL,讓系統(tǒng)為這兩個對象賦予默認的安全描述符。CreateProcess(“….

12、exe”,NULL,NULL,NULL…),BOOL bInheritHandlesbInheritHandles用來指定父進程隨后創(chuàng)建的子進程是否能夠繼承父進程的對象句柄。如果該參數(shù)為TRUE,那么父進程的每個可繼承打開句柄都能被子進程繼承。在本次實驗中,把這個參數(shù)設(shè)置為FALSE,因為子進程不需要繼承父進程的可繼承句柄。CreateProcess(“….exe”,NULL,NULL,NULL,FALSE,…),DWORD

13、 dwCreationFlagsdwCreationFlags指定進程創(chuàng)建的附加標記,也可以用于控制新進程的優(yōu)先級。如果只為了啟動子進程,不需要設(shè)置創(chuàng)建標記,則直接設(shè)置為0.如果不需要為應(yīng)用程序創(chuàng)建控制臺窗口,則可以設(shè)置該參數(shù)為CREATE_NO_WINDOW.如果需要創(chuàng)建新控制臺窗口,而不是繼承父進程的控制臺窗口,則設(shè)置為CREATE_NEW_CONSOLE.本次實驗中設(shè)置為該標記。CreateProcess(“….ex

14、e”,…, CREATE_NEW_CONSOLE, …)該參數(shù)可以取得創(chuàng)建標記很多,也可以用于設(shè)置新進程的優(yōu)先級。更多的設(shè)置可以參看MSDN。,LPVOID lpEnvironmentlpEnvironment是一個指向環(huán)境塊的指針,如果此參數(shù)是NULL,那么新進程使用調(diào)用進程的環(huán)境。通常都為此參數(shù)傳遞NULL。LPTSTR lpCurrentDirectorylpCurrentDirectory參數(shù)是一個指向空終止的字符串

15、,用來指定子進程當前的路徑,這個字符串必須是一個完整的路徑名,包括驅(qū)動器的標識符,如果此參數(shù)為NULL,那么新的子進程將于調(diào)用進程(父進程)用有相同的驅(qū)動器和目錄。CreateProcess(“….exe”,…, CREATE_NO_WINDOW,NULL,NULL,…),LPSTARTUPINFO lpStartupInfolpStartupInfo是一個指向STARTUPINFO結(jié)構(gòu)體的指針,用來指定新進程的主窗口將如何顯示。

16、typedef struct _STARTUPINFO { DWORD cb; LPTSTR lpReserved; LPTSTR lpDesktop; LPTSTR lpTitle; …… ……HANDLE hStdInput; HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO;,STARTUPINFO結(jié)構(gòu)體成員比較多,并不需要為

17、其所有成員都賦值。其中cb表示該結(jié)構(gòu)體本身的大小,以字節(jié)為單位,通常都要為其cb成員賦值,否則函數(shù)調(diào)用會失敗。在創(chuàng)建進程之前的準備工作就包括給該結(jié)構(gòu)體變量賦值。在本次實驗中,不需要設(shè)置其它啟動信息,所以直接給cb參數(shù)賦值就可以。STARTUPINFO sui;ZeroMemory(&sui,sizeof(sui));sui.cb=sizeof(STARTUPINFO);CreateProcess(…,&s

18、i,…);,,LPPROCESS_INFORMATION lpProcessInformationlpProcessInformation參數(shù)作為返回值使用,是一個指向PROCESS_INFORMATION結(jié)構(gòu)體的指針,用來接收關(guān)于新進程的標志信息。PROCESS_INFORMATION結(jié)構(gòu)體定義如下所示:typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HAN

19、DLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION;,,hProcess和hThread分別是標識新創(chuàng)建的進程句柄和新創(chuàng)建進程的主線程句柄;dwProcessId和dwThreadId分別是全局進程標識符和全局線程標識符,前者用來標識一個進程,后者用來標識一個線程。(當啟動一個進程時,系統(tǒng)會為此進程分配一個標識符,同時這個進程中的線程

20、也會被分配一個標識符,在一個進程運行時,該進程的標識符和線程的標識符是唯一的,停止后,這些標識符可能會被系統(tǒng)分配給其它進程和線程。),,在創(chuàng)建進程之前的另一項準備工作就是要定義PROCESS_INFORMATION 結(jié)構(gòu)體變量,準備用于接收創(chuàng)建進程后返回的信息。PROCESS_INFORMATION pi;CreateProcess(…,&si,&pi);,,CreateProcess函數(shù)的返回值創(chuàng)建進程成功后,

21、該函數(shù)返回TRUE,否則返回FALSE.在程序中需要判斷進程創(chuàng)建是否成功If(!CreateProcess(…,&si,&pi))//創(chuàng)建不成功Return;Else//創(chuàng)建成功//父進程繼續(xù)執(zhí)行,,在父進程創(chuàng)建子進程后,子進程就開始運行;同時父進程計算1——100的和。因為計算太快,為了方便觀察父進程和子進程系統(tǒng)工作的過程,可以在計算過程使用Sleep 函數(shù),強制讓父進程的主線程休眠。Sleep

22、函數(shù)定義如下:void Sleep( DWORD dwMilliseconds);//休眠一段時間,以ms為單位Sleep(1000);//表示休眠1秒,計算完之后等待子進程完成它的工作。等待子進程完成可以用WaitForSingleObject函數(shù)實現(xiàn)等待。該函數(shù)定義如下:DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds );,,hHandl

23、e參數(shù)指定需要等待的對象句柄。dwMilliseconds 參數(shù)指定需要等待的時間,以ms為單位。0表示立即返回不等待。INFINITE表示等待直到對象句柄可用。WaitForSingleObject( pi.hProcess,INFINITE);,,父進程等待子進程完成工作后,父進程需要讀取文件內(nèi)容并輸出,是文件的一種操作。這在下面在子進程中介紹文件操作時一起系統(tǒng)介紹。,,子進程的工作主要涉及的是文件操作。創(chuàng)建文件可以用f

24、open函數(shù)FILE *fopen( //返回一個指向文件結(jié)構(gòu)體的指針const char *filename, //打開或創(chuàng)建的文件名const char *mode //打開或創(chuàng)建方式,即設(shè)定讀寫權(quán)限); Fopen函數(shù)既可以創(chuàng)建文件也可以打開已存在的文件FILE *pFile=fopen("1.txt","w");,子進程,文件寫操作可以用fwrite函數(shù)size_t f

25、write( const void *buffer, //指向要寫入內(nèi)容的文件指針size_t size, //每次寫入大小,字節(jié)為單位size_t count, //寫入次數(shù)FILE *stream //一個指向文件結(jié)構(gòu)體的指針,表示將要寫操作的文件);fwrite("Xidian University",1,strlen("Xidian University"),pFile);,

26、,讀文件操作用fread函數(shù)size_t fread( const void *buffer, //指向要讀取內(nèi)容的文件指針size_t size, //每次讀取大小,字節(jié)為單位size_t count, //讀取次數(shù)FILE *stream //一個指向文件結(jié)構(gòu)體的指針,表示將要寫讀取操作的文件);,,在每次寫入文件盒讀取文件操作后,關(guān)閉文件,使用fclose函數(shù)int fclose( FILE *stream );/

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論