1、什么是進程?
::一般將進程定義成一個正在運行的程序的一個實例。進程由兩部分組成:
①、一個內核對象,操作系統用它來管理進程。內核對象也是系統保存進程統計信息的地方。
②、一個地址空間,其中包含所有執行體(executable)或DLL模塊的代碼和數據。此外,它還包含動態內存分配,比如線程堆棧和堆的分配。
進程與線程的關系:
①、一個進程創建的時候,系統會自動創建它的第一個線程,這稱為主線程(primary thread)。
②、進程要做任何事情,都必須讓一個線程在它的上下文中運行。如果沒有線程要執行進程地址空間包含的代碼,進程就失去了繼續存在的理由。所以,系統會自動銷毀進程及其地址空間。
③、一個進程可以有多個線程,所有線程都在進程的地址空間中“同時”執行代碼。為此,每個線程都有它自己的一組CPU寄存器和它自己的堆棧。對于所有要運行的線程,操作系統會輪流為每個線程調度一些CPU時間。它會采取round-robin(輪詢或輪流)方式,為每個線程都分配時間片,從而營造出所有線程都在“并發”運行的假象。
2、系統如何創建一個進程內核對象來管理每個進程。
當一個進程被初始化時,系統要為它分配一個句柄表(空的,也就是用來管理進程的內核對象)。該句柄表只用于內核對象(而不用于用戶對象和gdi對象)。句柄表是一個數據結構的數組,每個結構都包含一個指向內核對象的指針,一個 訪問屏蔽(DWORD)和一個標志(DWORD)。
:::當進程中的線程調用創建內核對象的函數(比如 CreatFileMapping)時,內核就為該對象分配一個內存塊并對它初始化。同時對進程的句柄表進行掃描,找出一個空項,填充內核對象數據結構的內存地址到該頂的指針成員,設置訪問屏蔽和標志。
::: 用于創建內核對象的所有函數均返回與進程相關的句柄。該句柄實際上是放入進程的句柄表中的索引 (由此可知,句柄是與進程相關的,不能由其他進程直接成功地使用)。但這只適用部分系統,句柄的含義可能隨時變更。 應用程序在運行時有可能泄漏內核對象,但是當進程終止時系統將能確保所有內容均被正確地清除。這個情況也適用于所有對象,資源和內存塊,也就是說當進程終止運行時,系統將保證進程不會留 下任何對象。
3、如何利用與一個進程關聯的內核對象來操縱該進程。
4、進程的各種不同的屬性(或特性),以及用于查詢和更改這些屬性的幾個函數。
實例句柄、前一個實例句柄、進程的命令行、進程的環境變量、進程當前所在的驅動器和目錄、還有版本問題等
5、如何利用一些函數在系統中創建或生成額外的進程。
我們用CreateProcess函數來創建一個進程,參考MSDN。當一個線程調用CreateProcess時,系統會做如下工作:
(1)、系統將創建一個進程內核對象,其初始使用計數為1。進程內核對象不是進程本身,而是操作系統用來管理這個進程的一個小型數據結構(該內核對象是用來管理新進程的)。
(2)、系統為新進程創建一個虛擬地址空間,并將執行體文件(和所有必要的DLL)的代碼及數據加載到進程的地址空間。
(3)、系統為新進程的主線程創建一個線程內核對象(使用計數為1)。和進程內核對象一樣,線程內核對象也是一個小型數據結構,操作系統用它來管理這個線程。這個主線程一開始就會執行由鏈接器設為應用程序入口的C/C++運行時啟動例程,并最終調用你的WinMain,wWinMain,main或wmain函數。
(4)、如果系統成功創建了新進程和主線程,CreateProcess將返回TRUE。
創建子進程后:
創建一個進程內核對象時,系統會為此對象分配一個獨一無二的標識符,系統中沒有別的進程內核對象會有相同的ID編號
6、如何終止線程。
關閉到一個進程或線程的句柄,不會強迫系統殺死此進程或線程。關閉句柄只是告訴系統你對進程或線程的統計數據
不再感興趣了。進程或線程會繼續執行,直至自行終止。(計數,重點是計數)
進程可以通過以下4種方式終止:
(1)、主線程的入口函數返回(強烈推薦的方式)。
讓主線程的入口函數返回,可以保證發生以下幾件事情:
?? 該線程創建的任何C++對象都將由這些對象的析構函數正確銷毀。
?? 操作系統將正確釋放線程堆棧使用的內存。
?? 系統將進程的退出代碼(在進程內核對象中維護)設為你的入口函數的返回值。
?? 系統遞減進程內核對象的使用計數。
(2)、進程中的一個線程調用ExitProcess函數(要避免這個方式)
進程會在該進程中的一個線程調用ExitProcess函數時終止:
VOID ExitProcess(UINT fuExitCode);
一旦你的應用程序的主線程從它的入口函數返回,那么不管當前在進程中是否正在運行其他線程,都會調用ExitProcess來終止進程。不過,如果在入口函數中調用ExitThread,而不是調用ExitProcess或者簡單地返回,應用程序的主線程將停止執行,但只要進程中還有其他線程正在運行,進程就不會終止。
(3)、另一個進程中的線程調用TerminateProcess函數(要避免這個方式)
調用TerminateProcess也可以終止一個進程,但是進程無法將它在內存中的任何信息轉儲到磁盤上。
(4)、進程中的所有線程都“自然死亡”(這是很難發生的)
posted on 2011-10-07 11:19
Yu_ 閱讀(412)
評論(0) 編輯 收藏 引用 所屬分類:
Windows程序設計