windows 核心程式設計 筆記之 程序

2021-06-14 09:46:44 字數 3758 閱讀 5091

內容:windows程序(process)

如上圖所示,windows任務管理器中的程序tab列中列出了系統管理的所有程序,我們經常利用任務管理器來結束某個沒有得到響應的應用程式,但是,作為乙個windows程式設計師,我們應該有這樣的疑問:程序是什麼東西?系統為什麼會存在程序?程序有哪些屬性?程序是怎樣工作的?以及我們自己寫的程式中能不能用程序,且應該怎樣使用....?......帶著這些問題,我自己參考了微軟技術叢書--《windows核心程式設計》,現在請允許我將自己獲取的一些知識總結出來,希望對初學的大家有些許幫助。

「程序是乙個正在執行的例項」,《核心程式設計》是這樣給程序下定義的

「被載入到記憶體中執行的程式例項,稱為程序(process)」《作業系統》的定義

的確,當我們在windows某個驅動碟符下的資料夾中雙擊左鍵執行某個檔案程式,然後程式執行,這就是乙個例項,我在前面章節中也說過,有些程式只允許乙個例項執行,最具代表性的就是網路遊戲,當我們執行網路遊戲程式(如cf),會順利執行,彈出乙個視窗,再次雙擊檔案,還是只有乙個視窗,甚至第二次執行時會彈出乙個提示框,類似於:「當前已有...例項在執行」(如:dnf),我想舉了這樣一些例子,大家應該明白了什麼是例項了.

程序作為乙個正在執行的例項,那麼程序內部到底是怎樣實現的?

「程序有兩個部分組成:

1.乙個核心物件,作業系統用這個核心物件來管理程序

2.乙個位址空間,其中包含所有可執行檔案或dll模組的**和資料,此外還包含動態記憶體分配,比如執行緒堆疊和堆的分配。」(《windows核心程式設計》)

程序作為應用程式的一部分,作業系統是利用核心物件來管理程序,什麼是核心物件?

核心物件其實是個小型的資料結構,每當程序建立時由系統分配空間去建立乙個核心物件去管理程序,由這個核心物件去統計一些有關程序的一些資訊。

我們寫windows程式,每當進入winmain函式入口點,由系統分配位址空間,由cs:ip指向程式首位址,有系統建立程序,然後由這個程序去建立執行緒(有關執行緒,下面再述),這個程序就稱作主程序,其實程序具有「惰性」,就是因為程序要執行一些事務,必須由執行緒去執行,程序就相當於執行緒的容器,執行緒在程序的上下文中執行。

所以我們寫的程式最起碼都包含乙個程序和乙個執行緒,雖然我們沒有顯式地去建立這個程序和執行緒,這些工作都是有系統去完成的,一般的,如果我們的程式不是很強大,沒有必要去建立程序,因為下一章節介紹的執行緒會讓我們的程式更加容易實現(設計到程序間通訊相對於執行緒間通訊要複雜),還有,如果我們寫gui程式,一般由乙個執行緒去做這些介面工作,沒有必要去建立額外的執行緒。

為什麼存在程序?

windows作業系統是基於時間片分配的分時作業系統,對於只有乙個處理器的pc來說,系統要執行一堆程式,必須給每個程式分配乙個時間片,然後讓他們輪循執行,可以這麼說,在每個時刻,windows作業系統肯定只有乙個程式在執行,而在下一時刻,可能剛才執行的程式已經掛起,而這樣一些工作,系統就是利用程序來管理實現的。

每當程序建立,系統會將該程序加入乙個佇列,這個佇列一直在執行,對於佇列,我們知道,它是先進先出的乙個資料結構。系統建立這個佇列來容納所有建立的程序,然後讓他們輪詢執行,所以當應用程式過多時,系統的響應就就會越慢,這是顯而易見的,因為每個時刻只允許乙個程序執行,此時其他程序必須掛起,等待該程序執行的時間片結束,然後輪到下乙個要等待執行的程序執行。

我們自己的程式如何實現程序,多程序的程式好嗎?

實現程序的方法:

windows platform sdk提供了一些api供程式使用,可以很簡單的使用程序。

createprocess(...) 我們利用這個函式可以建立乙個程序,此時系統會分配乙個核心物件去管理它,這個函式返回的是乙個控制代碼(handle),所謂控制代碼,實際上是乙個識別符號,是記憶體空間的乙個基位址,系統會將這個基位址與程序的映像相關聯,不用想太多,我們只要知道,這個控制代碼就是用來標識程序就行了。(我們可以利用getmodulehandle(..)獲取一些有用的資訊,如果給引數傳入.exe檔案的路徑或者dll檔案路徑的話就會獲取該可執行檔案的控制代碼,如果傳null,就是獲取當前程式的主程序控制代碼(主程序基位址)),一旦我們對這個控制代碼不感興趣了(我們以後肯能用不到它了),就要呼叫closehandle(..)關閉控制代碼,記住,僅僅是關閉而已,該控制代碼標記的程序仍然在執行。

當我們想退出程序,如何實現?

exitprocess(..)可以顯式地結束某個程序

terminateprocess(..)讓外部的程序可以結束任何其他程序(任務管理器就是這樣實現結束程序的)

雖然有這樣一些api,但是windows並不提倡使用他們去結束程序,最好的方法就是我們程式設計師什麼也不做,讓程序在主調程序的入口點返回,這樣可以保證所有程序都可以順利結束自己的一生。

程序終止時,發生了什麼?

1.終止程序中遺留的任何執行緒

2.釋放程序分配所有物件

3.程序的退出**從still_active變為程序退出函式的**

4.程序核心物件的狀態變為觸發狀態

5.程序的核心物件的使用計數減1

分析:1,因為程序是執行緒的容器,程序並不執行任何**,一旦程序的生命週期結束,它所擁有的所有執行緒必將結束,很容易理解,因為裝執行緒的容器都沒了,執行緒也就不復存在了

2.程序既然是執行緒的容器,那麼執行緒中所擁有的任何核心物件必將銷毀,包括gdi物件(核心)和使用者物件。

5.管理程序的是系統的核心物件,而乙個程序可能被多個其他程序使用(開啟),而核心物件的使用計數就是標識使用次數的,例如:我們有時遇到這中情況,當我們的u盤插在usb介面上使用,然後退出u盤,可能會出現提示無法正常退出,因為某個u盤內的程式已經開啟,沒有關閉,但是我們怎麼找都找不到到底是哪個檔案沒有關閉,就是因為核心物件的使用計數沒有遞減到0,因為每當我們關閉乙個檔案,管理該檔案的核心物件的使用計數會減1,但是處於某種原因,在開啟另乙個檔案的時候,無意中開啟了另乙個檔案的控制代碼,可能是在內部共享某個dll,也可能是資料重疊,反正就是把那個檔案的控制代碼開啟了,於是核心物件的使用計數就加1,可是系統只知道,要想正常退出,必須保證核心物件的使用計數為零。。。

再次強調,我們應該盡可能的用執行緒代替程序,關於執行緒,請參照下一節:《windows核心程式設計》之執行緒、執行緒同步,執行緒與程序的關係,執行緒與作業的關係,程序間通訊和執行緒間通訊

windows核心程式設計筆記(一)

1.setwindowredraw 設定視窗的可重繪狀態 這個函式是不是把整個視窗 包括視窗控制項 的和重繪相關的訊號 遮蔽掉了?2.combobox setitemdata 巨集 函式原型 int combobox setitemdata hwnd hwndctl,空間控制代碼 int index...

《Windows核心程式設計》筆記1 核心物件

由於.net framework中很多地方需要用到以前win32中的一些知識點,不了解其中的來朧去脈學習起來會比較吃力,於是準備用點時間補一下windows 核心方面的知識點,參考書本是經典的核心物件是核心分配的乙個記憶體塊,這種記憶體塊是乙個資料結構,表示核心物件的各種特徵。並且只能由核心來訪問。...

Windows核心程式設計筆記 (3)核心物件

每個核心物件都只是乙個記憶體塊,它由作業系統核心分配,並只能由作業系統核心訪問,這個記憶體塊是乙個資料結構,其成員維護著於物件相關的資訊。少數成員是所有物件都有的,像安全描述符和使用計數等 大多數成員是特有的,像程序物件的程序id,檔案物件的位元組偏移量。由於核心物件的資料結構只能由作業系統核心訪問...