Windows核心编程 第五章 作业(下)
5.4 查詢作業統計信息
????前面已經介紹了如何使用 Q u e r y I n f o r m a t i o n J o b O b j e c t函數來獲取對作業的當前限制信息。也可以使用它來獲取關于作業的統計信息。例如,若要獲取基本的統計信息,可以調用Q u e r y I n f o r m a t i o n J o b O b j e c t,為第二個參數傳遞J o b O b j e c t B a s i c A c c o u n t i n g I n f o r m a t i o n ,并傳遞
J O B O B J E C T _ B A S I C _ A C C O U N T I N G _ I N F O R M AT I O N結構的地址:
?
表5 - 5簡要描述了它的各個成員。
?
? ? 除了查詢這些基本統計信息外,可以進行一次函數調用,以同時查詢基本統計信息和 I / O統計信息。為此,必須為第二個參數傳遞 J o b O b j e c t B a s i c A n d I o A c c o u n t i n g I n f o r m a t i o n ,并傳遞J O B O B J E C T _ B A S I C _ A N D _ I O _ A C C O U N T I N G _ I N F O R M AT I O N結構的地址:
?
? ? 如你所見,這個結構只返回一個J O B O B J E C T _ B A S I C _ A C C O U N T I N G _ I N F O R M AT I O N結構和I O _ C O U N T E R S結構:
?
? ? 該結構告訴你作業中的進程已經執行的讀、寫和非讀 /寫操作的數量(以及在這些操作期間傳送的字節數) 。另外,可以使用下面這個新的 G e t P r o c e s s I o C o u n t e r s函數,以便獲取不是這些作業中的進程的這些信息:
?
? ? 也可以隨時調用Q u e r y I n f o r m a t i o n J o b O b j e c t函數,以便獲取當前在作業中運行的進程的一組進程I D。若要進行這項操作,首先必須確定你想在作業中看到多少進程,然后必須分配足夠的內存塊,來放置這些進程I D的數組,并指定J O B O B J E C T _ B A S I C _ P R O C E S S _ I D _ L I S T結構的大小:
?
因此,若要獲得當前作業中的一組進程I D,必須執行類似下面的代碼:
?
? ? 這就是你使用這些函數的所有實現方法,不過操作系統實際上保存了更多的關于作業的信息。它是使用性能計數器來進行這項操作的。可以使用 Performance Data Helper函數庫(P D H . d l l)中的函數來檢索這些信息。也可以使用 Microsoft Management Console(MMC)的Performance Monitor Snap-In來查看作業信息。圖5 - 2顯示了系統中的作業對象可以使用的一些計數器。圖5 - 3顯示了可以使用的一些作業對象的明細計數器。也可以看到 J e ff的作業里有4個進程,即c a l c、c m d、n o t e p a d和w o r k p a d。
?
? ? 注意,當調用C r e a t e J o b O b j e c t函數時,只能為已經賦予名字的作業獲取性能計數器信息。由于這個原因,即使不打算按名字來共享跨越進程的作業對象,也應該創建帶有名字的這些對象。
5.5 作業通知信息
? ? 現在,已經知道了關于作業對象的基本知識,剩下要介紹的內容是關于通知的問題。例如,是否想知道作業中的所有進程何時終止運行或者分配的全部 C P U時間是否已經到期呢?也許想知道作業中何時生成新進程或者作業中的進程何時終止運行。如果不關心這些通知信息(而且許多應用程序也不關心這些信息) ,作業的操作非常容易。如果關心這些事件,那么還有一些工作要做。
? ? 如果關心的是分配的所有C P U時間是否已經到期, 那么可以非常容易地得到這個通知信息。當作業中的進程尚未用完分配的C P U時間時,作業對象就得不到通知。一旦分配的所有 C P U時間已經用完, Wi n d o w s就強制撤消作業中的所有進程,并將情況通知作業對象。通過調用Wa i t F o r S i n g l e O b j e c t (或類似的函數),可以很容易跟蹤這個事件。有時,可以在晚些時候調用
S e t I n f o r m a t i o n J o b O b j e c t函數,使作業對象恢復未通知狀態,并為作業賦予更多的C P U時間。
????當開始對作業進行操作時,我覺得當作業中沒有任何進程運行時,應該將這個事件通知作業對象。畢竟當進程和線程停止運行時,進程和線程對象就會得到通知。因此,當作業停止運行時它也應該得到通知。這樣,就能夠很容易確定作業何時結束運行。但是, M i c r o s o f t選擇在分配的C P U時間到期時才向作業發出通知,因為這顯示了一個錯誤條件。由于許多作業啟動時有一個父進程始終處于工作狀態,直到它的所有子進程運行結束,因此只需要在父進程的句柄上等待,就可以了解整個作業何時運行結束。 S t a r t R e s t r i c t e d P r o c e s s函數用于顯示分配給作業的C P U時間何時到期,或者作業中的進程何時終止運行。
? ? 前面介紹了如何獲得某些簡單的通知信息,但是尚未說明如何獲得更高級的通知信息,如進程創建/終止運行等。如果想要得到這些通知信息,必須將更多的基礎結構放入應用程序。特別是,必須創建一個 I / O完成端口內核對象,并將作業對象或多個作業對象與完成端口關聯起來。然后,必須讓一個或多個線程在完成端口上等待作業通知的到來,這樣它們才能得到處理。
? ? 一旦創建了I / O完成端口,通過調用S e t I n f o r m a t i o n J o b O b j e c t函數,就可以將作業與該端口關聯起來,如下面的代碼所示:
?
???當上面的代碼運行時,系統將監視該作業的運行,當事件發生時,它將事件送往 I / O完成端口(順便說一下,可以調用Q u e r y I n f o r m a t i o m J o b O b j e c t函數來檢索完成關鍵字和完成端口句柄。但是,這樣做的機會很少) 。線程通過調用G e t Q u e u e d C o m p l e t i o n S t a t u s函數來監控I / O完成端口:
?
????當該函數返回一個作業事件通知時,* p C o m p l e t i o n K e y包含了調用S e t I n f o r m a t i o n J o b O b j e c t時設置的完成關鍵字值,用于將作業與完成端口關聯起來。它使你能夠知道哪個作業存在一個事件。* p N u m B y t e s Tr a n s f e r r e d中的值用于指明發生了哪個事件。根據事件(見表5 - 6) ,*pOverlapped 中
的值將指明一個進程I D。
?
? ? 最后要說明的一點是,按照默認設置,作業對象是這樣配置的:當分配給作業的 C P U時間已經到期時,作業的所有進程均自動停止運行,而 J O B _ O B J E C T _ M S G _ E N D _ O F _ J O B _ T I M E通知尚未發送。如果想要防止作業對象撤消進程而只是通知你時間已經超過,必須執行下面這樣的代碼:
為作業設定結束時間而使用的另一個值是J O B _ O B J E C T _ T E R M I N AT E _ AT _ E N D _ O F _ J O B,這是作業創建時的默認值。
?
總結
以上是生活随笔為你收集整理的Windows核心编程 第五章 作业(下)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows核心编程 第五章 作业(上
- 下一篇: Intel汇编程序设计-整数算术指令(下