2009年12月30日 星期三

給應用程序加裝「看門狗」[

給應用程序加裝「看門狗」[轉]
January 9th, 2009 lonkil Visual C++ 發表評論 trackback
//最近比較懶,一直沒更新。by lonkil

今天無意中年到這篇文章,很不錯的主意,就轉過來了。

原文:http://blog.csdn.net/bhw98/archive/2004/04/28/19683.aspx

相信大多數的程序員或用戶,在Windows中見到類似於下面的親切而又溫馨的提示信息,都不會感到陌生:

「XXX執行了非法操作,將被關閉。要終止程序,請單擊;要調試程序,請單擊。」或者,「是否向Microsoft發送錯誤報告?,。」

如果這個程序運行在無人值守、需要保持連續工作狀態的場合,而其中的bug又一時難以排除,就需要採取應急措施,消除或減少程序出錯造成的影響。本文討論解決這個問題的辦法。

做過一定硬件開發的人都知道,惡劣的工作環境,帶有缺陷的硬件設計,不完善的算法等內外因素,都可能造成程序「跑飛」,因此專門加裝一個「看門狗」,負責監視程序主體,必要時產生復位中斷,有效地避免設備當機。

「看門狗」的思想,完全可以拿到高級語言編程中來用。基本做法是:設計一個簡單的監視程序做為主進程,將原來的工作程 序作為子進程,由主進程啟動子進程並監視子進程的運行狀態。子進程在發生嚴重錯誤時不彈出本文開始時描述的對話框,而是悄悄退出。主進程發現子進程退出 後,重新啟動子進程。如此反覆。

在具體實現上,下面以VC為例說明:

設置子進程為「靜默模式」
在系統初始化部分(CWinApp或main中的開頭),調用API函數SetErrorMode

SetErrorMode(SEM_NOGPFAULTERRORBOX);保證程序在發生嚴重錯誤時不彈出對話框,無需人工干預,自行退出。

啟動子進程
在主進程中,創建子進程並運行。假定子進程的可執行文件為work.exe,示意性代碼如下

STARTUPINFO si;
PROCESS_INFORMATION pi;

ZeroMemory( π, sizeof(pi) );
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);

// Start the child process
if (CreateProcess("work.exe", "", NULL, NULL, FALSE, 0, NULL, NULL, &si, π))
{
// success
… …
}CreateProcess有10個參數,看起來挺嚇人,其實並不複雜,很容易理解。最後一個參數會返回子進程的ID和句柄等信息,後面就是對進程ID或句柄進行監視。

監視子進程
定時檢查子進程是否在正常運行。有好幾個API都可以用於對指定ID的進程進行監視,像GetProcessVersion,GetProcessTimes,GetProcessIoCounters等,其中GetProcessVersion最簡單,只有一個參數:

DWORD GetProcessVersion( DWORD ProcessId);當子進程已經退出時,該函數返回0。

更為「專業」的函數是GetExitCodeProcess,它甚至能告訴我們子進程退出的原因:

BOOL GetExitCodeProcess(
HANDLE hProcess, // handle to the process
LPDWORD lpExitCode // termination status
);更進一步的考慮
為增強系統的可靠性,給工作程序加裝「看門狗」,不失為一種可行的技術方案。但如果有兩套用戶界面,看起來就有點不那 麼專業了。可將子進程設計為基於console的應用,不帶用戶界面,所有的信息都通過主進程窗口輸出。主進程CreateProcess的第6個參數需 加入CREATE_NO_WINDOW項,將子進程隱藏起來。這樣從用戶的角度看起來,就像只存在一個應用程序。

另一個問題是,如果用戶關閉主進程,如何同時關閉子進程?用TerminateProcess函數固然能結束子進程,但可能會造成內存洩漏等新問題。最好是主進程向子進程發出結束的消息並進行同步,使子進程能夠從容地退出。
再擴展一下,一個主進程可以同時管理多個子進程。典型的例子是利用多塊網卡進行抓包、分析、處理的系統,將每一塊網卡應用與一個子進程綁定,而主進程負責監視所有的子進程的工作。
上面的討論涉及到進程間通信(IPC)問題。解決的辦法有很多,像file mapping, mailslot, pipe, DDE, COM, RPC, clipboard, socket, WM_COPYDATA等都能達到目的,可根據個人喜好和具體情況採用。

參考來源:

"給應用程序加"
- 给应用程序加装“看门狗”[转] « Vc爱好者 v3.0 (在「Google 網頁註解」中檢視)

沒有留言:

張貼留言