《電子技術(shù)應(yīng)用》
您所在的位置:首頁 > 其他 > 設(shè)計(jì)應(yīng)用 > 基于分布式環(huán)境的子進(jìn)程監(jiān)控軟件設(shè)計(jì)與實(shí)現(xiàn)
基于分布式環(huán)境的子進(jìn)程監(jiān)控軟件設(shè)計(jì)與實(shí)現(xiàn)
來源:微型機(jī)與應(yīng)用2013年第7期
張 虎,黃海于
(西南交通大學(xué) 信息科學(xué)與技術(shù)學(xué)院,四川 成都 610031)
摘要: 針對分布式系統(tǒng)環(huán)境下,計(jì)算資源代理對其子進(jìn)程監(jiān)控的方法單一,且不能準(zhǔn)確獲取子進(jìn)程運(yùn)行狀態(tài)的問題,提出了一種根據(jù)子進(jìn)程的窗口句柄定時(shí)檢測子進(jìn)程運(yùn)行狀態(tài)的方法。該方法首先根據(jù)子進(jìn)程的不同類型采用不同的方法獲取子進(jìn)程的窗口句柄,然后根據(jù)子進(jìn)程的窗口句柄定時(shí)獲取子進(jìn)程的運(yùn)行狀態(tài),最后將傳統(tǒng)的等待子進(jìn)程退出的方法引入到本應(yīng)用中。運(yùn)行結(jié)果表明,本方法可以及時(shí)準(zhǔn)確檢測出Windows環(huán)境下子進(jìn)程的運(yùn)行狀態(tài),并在子進(jìn)程異常退出時(shí),可以準(zhǔn)確地獲取其異常退出碼。
Abstract:
Key words :

摘  要: 針對分布式系統(tǒng)環(huán)境下,計(jì)算資源代理對其子進(jìn)程監(jiān)控的方法單一,且不能準(zhǔn)確獲取子進(jìn)程運(yùn)行狀態(tài)的問題,提出了一種根據(jù)子進(jìn)程的窗口句柄定時(shí)檢測子進(jìn)程運(yùn)行狀態(tài)的方法。該方法首先根據(jù)子進(jìn)程的不同類型采用不同的方法獲取子進(jìn)程的窗口句柄,然后根據(jù)子進(jìn)程的窗口句柄定時(shí)獲取子進(jìn)程的運(yùn)行狀態(tài),最后將傳統(tǒng)的等待子進(jìn)程退出的方法引入到本應(yīng)用中。運(yùn)行結(jié)果表明,本方法可以及時(shí)準(zhǔn)確檢測出Windows環(huán)境下子進(jìn)程的運(yùn)行狀態(tài),并在子進(jìn)程異常退出時(shí),可以準(zhǔn)確地獲取其異常退出碼。
關(guān)鍵詞: 分布式系統(tǒng);Windows運(yùn)行環(huán)境;代理;子進(jìn)程的管理和監(jiān)控;窗口句柄

 隨著高速列車仿真模擬、物聯(lián)網(wǎng)應(yīng)用等領(lǐng)域?qū)τ?jì)算機(jī)計(jì)算速度要求的不斷提高,單個的計(jì)算機(jī)已無法滿足高計(jì)算速度的要求。將一個大的計(jì)算任務(wù)分解成若干個小的計(jì)算任務(wù),并利用分布式系統(tǒng)[1]將各計(jì)算任務(wù)分散到不同的計(jì)算機(jī)上,以獨(dú)立進(jìn)程的形式進(jìn)行并行計(jì)算是一種比較好的解決方法。而對各獨(dú)立進(jìn)程的運(yùn)行狀態(tài)的實(shí)時(shí)監(jiān)控和管理是實(shí)現(xiàn)分布式系統(tǒng)高效運(yùn)行和管理的基礎(chǔ)。但是傳統(tǒng)的子進(jìn)程監(jiān)控只能對子進(jìn)程是否正在運(yùn)行或者退出做出判斷,無法判斷子進(jìn)程是否處在掛起狀態(tài),也無法及時(shí)地獲取子進(jìn)程的退出碼。
 針對上述需求,本文提出了一種根據(jù)子進(jìn)程的窗口句柄來檢測當(dāng)前子進(jìn)程運(yùn)行狀態(tài)的方法,并結(jié)合傳統(tǒng)的子進(jìn)程管理監(jiān)控方法,設(shè)計(jì)并實(shí)現(xiàn)了一種實(shí)時(shí)的子進(jìn)程管理監(jiān)控軟件。該軟件用于啟動和監(jiān)控分布式系統(tǒng)中任務(wù)調(diào)度器分配給本機(jī)的任務(wù)。目前該軟件可以檢測子進(jìn)程的三個狀態(tài):正常運(yùn)行、退出、掛起;可以及時(shí)的將子進(jìn)程的退出碼[2]反饋給分布式系統(tǒng)的任務(wù)調(diào)度器,為任務(wù)調(diào)度器[3]高效利用計(jì)算資源提供了一定的依據(jù);并且為開發(fā)人員根據(jù)進(jìn)程的異常退出碼對程序進(jìn)行查錯提供了方便。
1 傳統(tǒng)子進(jìn)程監(jiān)控方法
 通常Windows系統(tǒng)使用CreateProcess函數(shù)來新建一個子進(jìn)程。其中CreateProcess函數(shù)的最后一個參數(shù)的類型是LPPROCESS_INFORMATION結(jié)構(gòu)體,成功創(chuàng)建子進(jìn)程后,子進(jìn)程的基本信息就存儲在該結(jié)構(gòu)體中。在Windows API的定義中,該結(jié)構(gòu)體包含了子進(jìn)程的進(jìn)程句柄、進(jìn)程ID、主線程句柄和主線程ID。創(chuàng)建子進(jìn)程成功后可以通過子進(jìn)程的句柄和Windows提供的wait[4]系列函數(shù)等待子進(jìn)程或者子進(jìn)程組變?yōu)閟ignaled狀態(tài),從而立刻獲知該進(jìn)程或進(jìn)程組退出。
 傳統(tǒng)的子進(jìn)程監(jiān)控方法的好處是:如果子進(jìn)程確實(shí)正常退出,則該方法能夠及時(shí)地獲知子進(jìn)程已經(jīng)退出,并且可以通過Windows提供的API函數(shù)GetExitCodeProcess獲取子進(jìn)程的退出碼。但是在大量的實(shí)際應(yīng)用過程中,該方法暴露出了其不足之處。例如,創(chuàng)建一個有錯的(如除0錯誤)MFC程序,然后通過以上方法啟動這個有錯的進(jìn)程,再用wait系列函數(shù)等待子進(jìn)程退出。當(dāng)子進(jìn)程運(yùn)行到錯誤的語句時(shí)會彈出一個錯誤窗口,如圖1所示。

 這時(shí)wait系列函數(shù)沒有返回,說明子進(jìn)程還處在nonsignaled狀態(tài)。用GetExitCodeProcess函數(shù)獲取該子進(jìn)程的退出碼時(shí),得到的退出碼為STILL_ACTIVE,也就是說父進(jìn)程認(rèn)為子進(jìn)程還在正常運(yùn)行,無法獲取子進(jìn)程的退出碼。
 如果在分布式系統(tǒng)中出現(xiàn)這種子進(jìn)程明明已經(jīng)出錯導(dǎo)致無法繼續(xù)運(yùn)行,但是其監(jiān)控系統(tǒng)認(rèn)為其還在正常運(yùn)行的情況,會嚴(yán)重影響分布式系統(tǒng)的負(fù)載均衡,不利于分布式系統(tǒng)高效的運(yùn)行和管理。
2 判斷子進(jìn)程的類型
 Windows支持兩種類型的應(yīng)用程序。一種是基于圖形用戶界面(GUI)的應(yīng)用程序,另一種是基于控制臺用戶界面(CUI)的應(yīng)用程序[5]。
 基于控制臺的應(yīng)用程序?qū)儆谖谋静僮鞯膽?yīng)用程序。它通常不能用于創(chuàng)建窗口和處理消息,并且不需要圖形用戶界面。雖然基于CUI的應(yīng)用程序包含在屏幕上的窗口中,但是窗口只包含文本。命令外殼程序CMD.exe是典型的基于CUI的應(yīng)用程序。基于GUI的應(yīng)用程序有一個圖形前端程序,它能創(chuàng)建窗口,擁有菜單,可以通過對話框與用戶打交道,并且可以使用所有的標(biāo)準(zhǔn)Windows組件。
 這兩種類型的應(yīng)用程序之間的界限是非常模糊的,所以Windows沒有提供API用來判斷一個程序是基于GUI的還是CUI的。但是可以通過應(yīng)用程序在運(yùn)行時(shí)加載的動態(tài)庫[6]來判斷應(yīng)用程序的類型。
 user32.dll和comctl32.dll兩個模塊[7]是Windows用戶界面相關(guān)應(yīng)用程序接口,包括窗口消息處理,基本用戶界面等特性。結(jié)合大量的測試得出,基于GUI的應(yīng)用程序在運(yùn)行時(shí)肯定會加載這兩個模塊,而單純的基于CUI的應(yīng)用程序在運(yùn)行時(shí)是不會加載這兩個模塊的。因此,可以通過檢測代理,新啟動的應(yīng)用程序是否加載了user32.dll和comctl32.dll這兩個模塊來區(qū)分應(yīng)用程序類型。
 接下來的工作就是如何檢測新啟動的進(jìn)程加載了哪些模塊。在Windows API中提供了枚舉一個進(jìn)程所加載模塊句柄的接口:EnumProcessModules函數(shù)。該函數(shù)的原型為:
BOOL WINAPI EnumProcessModules(
  __in          HANDLE     hProcess,
  __out         HMODULE * lphModule,
  __in          DWORD      cb,
  __out         LPDWORD   lpcbNeeded
);
 該函數(shù)接收一個進(jìn)程的句柄,輸出該進(jìn)程所加載的所有模塊的句柄數(shù)組,并且通過lpcbNeeded參數(shù)輸出所有模塊的句柄所占的字節(jié)數(shù)。因?yàn)樵趩幼舆M(jìn)程的時(shí)候,肯定能夠得到子進(jìn)程的進(jìn)程ID和進(jìn)程句柄,所以通過EnumProcessModules函數(shù)可以方便地得到某個特定的進(jìn)程所加載模塊的句柄。但是通過模塊的句柄,還無法直觀的得到進(jìn)程加載的模塊的名稱。這種情況下,可以通過vc提供的另外一個接口:GetModuleFileNameEx函數(shù)來獲取各模塊的名稱。GetModuleFileNameEx的函數(shù)原型為:
DWORD WINAPI GetModuleFileNameEx(
  __in          HANDLE   hProcess,
  __in          HMODULE hModule,
  __out         LPTSTR    lpFilename,
  __in          DWORD    nSize
);
 該函數(shù)接收一個進(jìn)程的句柄和模塊的句柄,通過lpFilename參數(shù)以字符串的形式輸出模塊的具體名稱。進(jìn)程的句柄在啟動進(jìn)程時(shí)就可以獲得,模塊的句柄就是之前通過EnumProcessModules函數(shù)獲得模塊句柄數(shù)組。
 計(jì)算資源上運(yùn)行的代理通過這兩個API的配合使用,可以準(zhǔn)確獲得啟動的子進(jìn)程所加載的模塊具體的名稱,也就能夠確定子進(jìn)程是否加載了user32.dll和comctl32.dll兩個模塊。這樣代理就可以確定子進(jìn)程是基于GUI的應(yīng)用程序還是基于CUI的應(yīng)用程序。在確定了應(yīng)用程序的類型之后,根據(jù)各種類型應(yīng)用程序的不同特點(diǎn),采用不同的子進(jìn)程監(jiān)控方法對其進(jìn)行監(jiān)控。
3 基于窗口句柄對子進(jìn)程監(jiān)控的方法
 在Windows系統(tǒng)中不論是GUI應(yīng)用程序還是CUI應(yīng)用程序,在程序啟動時(shí)都會生成一個窗口。不同的是,GUI應(yīng)用程序是根據(jù)自己的程序需求生成窗口,CUI應(yīng)用程序是系統(tǒng)為其加載的一個文本控制臺窗口。系統(tǒng)為每一個窗口生成了唯一的標(biāo)示,即窗口句柄。而且Windows提供了一個通過窗口句柄來檢測應(yīng)用程序是否處于掛起狀態(tài)的API函數(shù),該函數(shù)的原型為:BOOL IsHungAppWindow(HWND hWnd)。該函數(shù)接收一個窗口句柄作為輸入?yún)?shù),并且判斷該窗口所屬的進(jìn)程是否處于掛起狀態(tài)。當(dāng)進(jìn)程處于掛起狀態(tài)時(shí),函數(shù)返回TRUE;當(dāng)進(jìn)程處于非掛起狀態(tài)時(shí),函數(shù)返回FALSE。只要能獲取到進(jìn)程所對應(yīng)的窗口句柄,就能夠通過定時(shí)調(diào)用IsHungAppWindow函數(shù)判斷GUI應(yīng)用程序是否處于掛起狀態(tài)。
 但是,在子進(jìn)程創(chuàng)建的過程中,父進(jìn)程只能獲取到該子進(jìn)程的進(jìn)程句柄和該進(jìn)程的主線程句柄,無法獲取到子進(jìn)程所對應(yīng)的窗口句柄。所以,如何獲取子進(jìn)程所對應(yīng)的窗口句柄是基于GUI的應(yīng)用程序監(jiān)控方法的關(guān)鍵。
 獲取窗口句柄的方法有很多種,本應(yīng)用中針對GUI應(yīng)用程序和CUI應(yīng)用程序的不同特點(diǎn)采用了不同的方法獲取這兩種應(yīng)用程序的窗口句柄。
3.1 獲取GUI應(yīng)用程序的窗口句柄
 如果應(yīng)用程序是一個基于GUI的應(yīng)用程序,則操作系統(tǒng)在啟動的過程中不會為應(yīng)用程序創(chuàng)建控制臺窗口,而只是加載應(yīng)用程序。當(dāng)基于GUI的應(yīng)用程序啟動之后,就根據(jù)程序自身的需要生成特定的窗口。這樣窗口的進(jìn)程ID即為應(yīng)用程序的進(jìn)程ID。
 針對GUI應(yīng)用程序的窗口進(jìn)程ID即為應(yīng)用程序進(jìn)程ID的特點(diǎn),獲取GUI應(yīng)用程序窗口句柄采用的方法是在創(chuàng)建子進(jìn)程之后遍歷系統(tǒng)中所有窗口,在遍歷的過程中根據(jù)窗口的句柄來獲取窗口所對應(yīng)的進(jìn)程的ID;將獲取到的窗口進(jìn)程ID與創(chuàng)建的子進(jìn)程的ID進(jìn)行匹配。如果匹配成功則該窗口就是子進(jìn)程創(chuàng)建的窗口,可以通過該窗口的句柄調(diào)用IsHungAppWindow函數(shù)來判斷該子進(jìn)程是否處于掛起的狀態(tài)。
 在遍歷窗口句柄時(shí),是通過GetTopWindow和GetNextWindow這兩個API函數(shù)協(xié)同工作完成的;而根據(jù)窗口句柄來獲取窗口所對應(yīng)的進(jìn)程ID是通過GetWindowThreadProcessId函數(shù)實(shí)現(xiàn)的。具體的實(shí)現(xiàn)代碼如下:
HWND GetWindowHandleByPid(DWORD dwProcessID)
{
    HWND h=GetTopWindow(0);
    while(h)
    {
        DWORD pid=0;
        DWORD dwThreadID=GetWindowThreadProcessId(h,&pid);
        if(dwThreadID!=0)
        {
            if(pid==dwProcessID)
            {
                return h;
            }
        }
        h=GetNextWindow(h,GW_HWNDNEXT);
    }
    return NULL;
 }
 該函數(shù)的輸入?yún)?shù)為需要獲取窗口句柄的進(jìn)程的ID。如果查找成功則返回進(jìn)程所對應(yīng)窗口的窗口句柄;如果不成功則返回NULL。
3.2 獲取CUI應(yīng)用程序的窗口句柄
 通常情況下,基于CUI的應(yīng)用程序不會創(chuàng)建窗口和處理消息,并且不需要圖形用戶界面。但是Windows系統(tǒng)會為CUI的應(yīng)用程序自動加載一個文本控制臺窗口的外殼程序。CUI應(yīng)用程序的標(biāo)準(zhǔn)輸入輸出都是在這個外殼程序中完成的,所以也可以通過判斷該控制臺窗口是否處于掛起狀態(tài)來判斷CUI應(yīng)用程序的狀態(tài),即通過IsHungAppWindow函數(shù)來判斷應(yīng)用程序是否掛起。
 但是,Windows對CUI應(yīng)用程序的這種處理方式使得CUI程序與CUI程序的窗口具有不同的進(jìn)程ID。這樣就不能通過匹配程序進(jìn)程ID和窗口進(jìn)程ID的方法來確定某一個窗口是否屬于某一個應(yīng)用程序。
針對CUI應(yīng)用程序的以上特點(diǎn),本應(yīng)用獲取CUI應(yīng)用程序窗口句柄的方法是通過檢測窗口的標(biāo)題來確定該窗口是否屬于某一個CUI程序。采用這種方法的原因是基于CUI的窗口標(biāo)題肯定為該CUI程序的絕對路徑,并且在分布式計(jì)算的環(huán)境下,各個任務(wù)的子進(jìn)程可能同名但是肯定是存在于不同的目錄下的。所以通過標(biāo)題來確定一個窗口是否屬于CUI程序在本應(yīng)用環(huán)境下完全可行。
基于CUI子進(jìn)程的監(jiān)控方法是在啟動子進(jìn)程之后,根據(jù)子進(jìn)程的絕對路徑調(diào)用FindWindow系統(tǒng)函數(shù)來獲取該CUI子進(jìn)程的窗口句柄,這樣就可以通過定時(shí)調(diào)用IsHungAppWindow函數(shù)來檢測應(yīng)用程序的運(yùn)行狀態(tài)。
4 與傳統(tǒng)方法相結(jié)合的子進(jìn)程監(jiān)控方法
 以上介紹了通過窗口句柄對各種子進(jìn)程運(yùn)行狀態(tài)監(jiān)控的可行性。但是,基于窗口句柄檢測子進(jìn)程運(yùn)行狀態(tài)的方法是定時(shí)檢測子進(jìn)程的運(yùn)行狀態(tài)。所以如果定時(shí)檢測的時(shí)間較長時(shí),則缺乏好的實(shí)時(shí)性;如果定時(shí)檢測的時(shí)間較短時(shí),則增加了計(jì)算資源的負(fù)載。本應(yīng)用在綜合考慮了以上問題之后,采用了定時(shí)檢測子進(jìn)程的運(yùn)行狀態(tài)和開辟新的線程等待子進(jìn)程退出兩種手段相結(jié)合的方法來監(jiān)控子進(jìn)程的運(yùn)行狀態(tài)。這樣同時(shí)確保了檢測子進(jìn)程運(yùn)行狀態(tài)的實(shí)時(shí)性又彌補(bǔ)了傳統(tǒng)子進(jìn)程檢測方法在子進(jìn)程出現(xiàn)掛起狀態(tài)時(shí)無法檢測的問題。
在分布式計(jì)算環(huán)境下,計(jì)算資源上的代理啟動子進(jìn)程的時(shí)間不確定,并且可能同時(shí)管理多個子進(jìn)程。所以為了方便管理,在本應(yīng)用中建立了帶頭結(jié)點(diǎn)的子進(jìn)程信息鏈表用于同時(shí)管理多個子進(jìn)程。鏈表的結(jié)構(gòu)體定義如下:
struct ProcessInfoList
{
     short int ProjectID; //進(jìn)程工程號
     short int ConditionID; //進(jìn)程工況號
     short int ModuleID;   //進(jìn)程模塊號
     short int flag;    //進(jìn)程運(yùn)行狀態(tài)。-1為未響應(yīng);
 //0為已退出;1為正在運(yùn)行
 HWND hProcessWND;     //進(jìn)程對應(yīng)的窗口句柄
 int ProcessType; //進(jìn)程的類型。1為GUI應(yīng)用程序;
 //0為CUI應(yīng)用程序
 int SendFlag;     
   //用于標(biāo)示是否已經(jīng)提示調(diào)度器該進(jìn)程已掛起
     PROCESS_INFORMATION  ProcessInfo; 
 //進(jìn)程的信息,包括進(jìn)程句柄和進(jìn)程ID等
     DWORD ExitCode;   //進(jìn)程退出時(shí)的退出碼
     TaskHistoryList *next;
};
 其中ProjectID、ConditionID、ModuleID在整個分布式計(jì)算系統(tǒng)中確定唯一一個子進(jìn)程,并且子進(jìn)程的可執(zhí)行文件根據(jù)這三個值的不同而存放在不同的目錄下。SendFlag變量是用于提示調(diào)度器該進(jìn)程是否已掛起,當(dāng)該值為1時(shí),說明已經(jīng)提示調(diào)度器該進(jìn)程掛起,不用重復(fù)提醒;當(dāng)該值為0時(shí),說明還未提示調(diào)度器該進(jìn)程已掛起。
4.1 定時(shí)檢測子進(jìn)程的運(yùn)行狀態(tài)
 代理啟動時(shí)會創(chuàng)建子進(jìn)程信息鏈表頭結(jié)點(diǎn),并會創(chuàng)建定時(shí)器T,定時(shí)遍歷子進(jìn)程信息鏈表。當(dāng)子進(jìn)程信息鏈表中除頭結(jié)點(diǎn)外沒有其他的結(jié)點(diǎn)時(shí),則等待下一次定時(shí)的到來;當(dāng)子進(jìn)程信息鏈表中除頭結(jié)點(diǎn)外還有其他進(jìn)程的信息結(jié)點(diǎn),則首先關(guān)閉定時(shí)器T;然后遍歷鏈表各個結(jié)點(diǎn)中的窗口句柄信息,根據(jù)進(jìn)程的窗口句柄判斷進(jìn)程是否處于掛起的狀態(tài),如果進(jìn)程處于掛起的狀態(tài),則及時(shí)將該進(jìn)程的信息及進(jìn)程的當(dāng)前運(yùn)行狀態(tài)發(fā)送給調(diào)度器,如果進(jìn)程沒有處于掛起狀態(tài),則繼續(xù)遍歷下一個結(jié)點(diǎn),最后遍歷完成之后重新創(chuàng)建定時(shí)器T,定時(shí)遍歷子進(jìn)程信息鏈表。經(jīng)過大量的實(shí)驗(yàn),最終將定時(shí)器的定時(shí)時(shí)間設(shè)為3 s,即每3 s檢查所有子進(jìn)程是否處于掛起狀態(tài)。
4.2 創(chuàng)建新的線程等待子進(jìn)程退出
 當(dāng)有任務(wù)提交給代理時(shí),代理首先啟動相應(yīng)的應(yīng)用程序,然后創(chuàng)建新的線程等待子進(jìn)程的退出,最后判斷子進(jìn)程的類型,獲取進(jìn)程的窗口句柄,為新啟動的應(yīng)用程序創(chuàng)建子進(jìn)程鏈表節(jié)點(diǎn)。其中等待子進(jìn)程退出線程中所做的工作有:(1)根據(jù)新啟動進(jìn)程的進(jìn)程句柄調(diào)用WaitForSingleObject函數(shù),等待子進(jìn)程的退出;(2)當(dāng)子進(jìn)程退出后獲取進(jìn)程的退出碼,并存放在相應(yīng)的子進(jìn)程信息鏈表結(jié)點(diǎn)中;(3)獲取退出碼之后,將該子進(jìn)程的基本信息、子進(jìn)程的當(dāng)前狀態(tài)、子進(jìn)程的退出碼發(fā)送給調(diào)度器,線程結(jié)束。
 以上介紹了在Windows系統(tǒng)環(huán)境下對基于GUI和基于CUI子進(jìn)程監(jiān)控的實(shí)現(xiàn)方法。該方法主要是通過定時(shí)檢測子進(jìn)程對應(yīng)的窗口是否掛起以及開辟新的線程等待子進(jìn)程退出兩種手段相結(jié)合的方式實(shí)現(xiàn)對子進(jìn)程的監(jiān)控。雖然通過定時(shí)檢測窗口是否掛起的方法存在缺乏實(shí)時(shí)性的問題,但是通過縮短定時(shí)時(shí)間也可以將時(shí)間控制在毫秒級,在絕大多數(shù)的分布式計(jì)算應(yīng)用系統(tǒng)中是可以接受的。
該方法解決了傳統(tǒng)的子進(jìn)程檢測方法無法檢測子進(jìn)程掛起狀態(tài)的問題。對子進(jìn)程運(yùn)行狀態(tài)的檢測更準(zhǔn)確,提高了分布式計(jì)算環(huán)境下的資源利用率。
參考文獻(xiàn)
[1] 葛澎.分布式計(jì)算技術(shù)概述[J].微電子學(xué)與計(jì)算機(jī),2012(5):201-204.
[2] DAVE T. Understanding exit codes[J]. Linux Journal, 2010(197):24-25.
[3] Xie Tao, Qin Xiao. A Security-qriented task scheduler for heterogeneous distributed systems[J]. Lecture Notes in Computer Science, 2006(4297):35-46.
[4] STRVENS W R, RAGO S A. UNIX環(huán)境高級編程(第2版)[M].尤晉元,張亞英,戚正偉譯.北京:人民郵電出版社, 2005:179-182.
[5] RICHTER J, NASARRE C. Windows核心編程(第5版)[M].葛子昂,周靖,廖敏譯.北京:清華大學(xué)出版社,2008:69-72.
[6] 高連生,盛柏林.動態(tài)鏈接庫在組態(tài)軟件中的應(yīng)用[J].工業(yè)控制計(jì)算機(jī),2010(6):21-22.
[7] 周超.Windows和Linux動態(tài)鏈接庫研究及應(yīng)用[D].上海:華東理工大學(xué),2007.
[8] Microsoft. QIsHungAppWindow function(Windows) [OL]. [2012-11-28]. http://msdn.microsoft.com/ZH-CN/library/windows/desktop/ms633526(v=vs.85).aspx

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載。