童 艷,方建勛
(解放軍91550部隊,遼寧 大連 116023)
實(shí)時測控數(shù)據(jù)處理軟件是測控系統(tǒng)的核心部件,主要負(fù)責(zé)接收各類傳感器測量數(shù)據(jù),通過實(shí)時數(shù)據(jù)處理和軌跡解算,與其他系統(tǒng)交互數(shù)據(jù)處理結(jié)果,完成測控任務(wù)[1]。近年來,隨著測控系統(tǒng)向多目標(biāo)多任務(wù)化方向發(fā)展,實(shí)時測控數(shù)據(jù)處理軟件的處理任務(wù)明顯增大,為保證實(shí)時性和可靠性,集中式處理模式越來越難以滿足更多的數(shù)據(jù)處理需求。為提高實(shí)時數(shù)據(jù)處理能力,基于集群技術(shù)建立一個計算功能強(qiáng)大、實(shí)時性強(qiáng)、可靠性高的實(shí)時測控集群系統(tǒng)勢在必行。
由于測控任務(wù)中通常面臨目標(biāo)型號不同、種類多樣等問題,每個型號任務(wù)對應(yīng)一套軟件,如此龐大的軟件以及多樣化的軟件版本,不利于軟件的開發(fā)和維護(hù)管理,且對于通用性的軟件升級改造復(fù)用性較差[2]。為規(guī)范軟件設(shè)計方法,提高實(shí)時數(shù)據(jù)處理軟件的通用性,本文從軟件結(jié)構(gòu)設(shè)計、通信機(jī)制、控制流程和算法模型庫等關(guān)鍵技術(shù)開展規(guī)范化設(shè)計研究,為后續(xù)實(shí)時測控數(shù)據(jù)處理軟件的版本固化和新軟件的通用化研發(fā)提供技術(shù)依據(jù)。
實(shí)時測控數(shù)據(jù)處理軟件在高精度時統(tǒng)信號同步下工作,完成測控目標(biāo)的實(shí)時測控數(shù)據(jù)處理、過程重演或模擬等任務(wù)。
過去采用集中式處理模式,依靠高性能小型機(jī)作為硬件平臺,實(shí)現(xiàn)強(qiáng)實(shí)時高可靠實(shí)時測控數(shù)據(jù)處理任務(wù)。但隨著測控技術(shù)和手段的不斷發(fā)展,傳感器的種類和數(shù)量、信息傳輸方式以及指揮控制手段都在發(fā)生巨大變化,使得集中處理模式在計算速度、吞吐能力、體系結(jié)構(gòu)等方面逐漸失去其優(yōu)勢,實(shí)時數(shù)據(jù)處理軟件開始向高性能、大容量的分布式處理模式發(fā)展。
為滿足實(shí)時數(shù)據(jù)處理軟件的強(qiáng)實(shí)時、高可靠需求,采用多進(jìn)程多線程程序設(shè)計思路,將軟件設(shè)計成由人機(jī)交互管理進(jìn)程、信號控制進(jìn)程、作業(yè)管理進(jìn)程、實(shí)時數(shù)據(jù)處理進(jìn)程、模擬重演進(jìn)程等五大進(jìn)程組成。同時,設(shè)計滿足實(shí)時性的通信機(jī)制,實(shí)現(xiàn)進(jìn)程間的信息實(shí)時交互,使進(jìn)程能夠相互協(xié)作完成實(shí)時數(shù)據(jù)處理任務(wù)??紤]軟件設(shè)計的通用性,采用系統(tǒng)參數(shù)配置管理和軟件模塊化加載方法,完成不同任務(wù)不同作業(yè)的軟件控制。對通用性較強(qiáng)的算法,采用模塊化設(shè)計方法建立算法模型庫,實(shí)現(xiàn)算法的通用化設(shè)計。
實(shí)時測控軟件規(guī)模龐大復(fù)雜,由多進(jìn)程多線程組成,各進(jìn)程或線程之間需要實(shí)時進(jìn)行信息交互,協(xié)作完成實(shí)時測控數(shù)據(jù)處理任務(wù)。
2.1.1 進(jìn)程內(nèi)通信
進(jìn)程內(nèi)即線程之間的信息交互采用全局變量和鎖存技術(shù)實(shí)現(xiàn)線程同步。
進(jìn)程中開設(shè)全局共享變量,進(jìn)程內(nèi)的各線程通過對全局變量的訪問達(dá)到信息交換的目的。
互斥鎖和條件變量則是作為線程間的同步方式,對線程共享區(qū)的訪問控制,需在每個共享數(shù)據(jù)結(jié)構(gòu)中設(shè)計讀寫鎖對象,通過互斥鎖和條件變量來實(shí)現(xiàn)嚴(yán)格同步。
2.1.2 進(jìn)程間通信
單一節(jié)點(diǎn)內(nèi)進(jìn)程間通信采用的有效解決方式是共享內(nèi)存結(jié)合信號量。
在進(jìn)程間通信采用共享內(nèi)存區(qū)實(shí)現(xiàn),它是通過將同一段物理內(nèi)存映射到不同進(jìn)程各自的地址空間中來實(shí)現(xiàn)的,當(dāng)多個進(jìn)程映射同一個共享內(nèi)存區(qū)對象時,如果其中某一個進(jìn)程向共享內(nèi)存區(qū)寫入了數(shù)據(jù),那么其他進(jìn)程就能夠立刻讀到該數(shù)據(jù)。由于映射到不同進(jìn)程的虛空間中,不同進(jìn)程可以直接使用,不需要進(jìn)行內(nèi)存的復(fù)制,沒有額外的與系統(tǒng)調(diào)用相關(guān)的開銷,所以從操作系統(tǒng)所能實(shí)現(xiàn)的所有IPC方法中,共享內(nèi)存區(qū)是解決進(jìn)程間數(shù)據(jù)傳遞的最快方法。
信號量主要是提供一種進(jìn)程間同步方式,控制各協(xié)作進(jìn)程對進(jìn)程共享區(qū)的訪問。當(dāng)向共享區(qū)中的某個區(qū)域?qū)憯?shù)據(jù)時,進(jìn)程將信號量一直鎖定到寫操作完成,以防止其他進(jìn)程此時訪問該共享區(qū)。當(dāng)進(jìn)程不再使用這段共享區(qū)時,則將該信號量解鎖,以便其他進(jìn)程使用。
對于分布式軟件布局來說,除了采取以上方法實(shí)現(xiàn)單一節(jié)點(diǎn)機(jī)內(nèi)部通信外,還要考慮不同節(jié)點(diǎn)間是如何實(shí)時通信的。目前,高速網(wǎng)絡(luò)配置和成熟的SOCKET通信手段是實(shí)現(xiàn)節(jié)點(diǎn)間實(shí)時通信最簡單有效的解決方式[3]。
基于實(shí)時性考慮,節(jié)點(diǎn)間信息的分發(fā)應(yīng)建立在UDP/IP協(xié)議基礎(chǔ)之上。對節(jié)點(diǎn)間需要實(shí)時交互的信息,如任務(wù)分配表、原始測量數(shù)據(jù)包、計算中間結(jié)果以及作業(yè)時間信息等,采用組播方式在節(jié)點(diǎn)之間信息傳輸。
節(jié)點(diǎn)間信息以20 Hz頻率進(jìn)行傳輸,完成處理后再以組播方式發(fā)送到相應(yīng)的節(jié)點(diǎn)機(jī)。節(jié)點(diǎn)間信息傳輸流程如圖1所示。
圖1 節(jié)點(diǎn)間信息傳輸流程
為提高通信效率,滿足系統(tǒng)的實(shí)時性要求,采用SOCKET的多路復(fù)用技術(shù)select監(jiān)測信息數(shù)據(jù)包是否到達(dá)[4]。當(dāng)有數(shù)據(jù)包到達(dá),先識別可進(jìn)行信息數(shù)據(jù)包讀操作的套接字,然后設(shè)置相應(yīng)的同步標(biāo)識并進(jìn)行寫入處理,完成后繼續(xù)等待下一數(shù)據(jù)包到達(dá),如果在等待過程中發(fā)生中斷,則返回繼續(xù)等待。由于通信傳輸時延等因素的存在,數(shù)據(jù)幀處理時用數(shù)據(jù)幀中的時間戳與當(dāng)前接收時間進(jìn)行比較,實(shí)現(xiàn)數(shù)據(jù)幀更新過濾,保證各節(jié)點(diǎn)能夠獲取最新的實(shí)時信息。最終將實(shí)時接收的信息存儲到共享內(nèi)存區(qū)或本地磁盤,供本地節(jié)點(diǎn)使用。
作為通用型實(shí)時數(shù)據(jù)處理軟件,在執(zhí)行不同的任務(wù)和作業(yè)時,各子功能模塊的加載和運(yùn)行情況是不一樣的,一般由主控模塊根據(jù)接收到的信號控制進(jìn)程內(nèi)其他各子功能模塊的運(yùn)行[7]。為實(shí)現(xiàn)系統(tǒng)的通用性和可靠性,每個功能模塊在設(shè)計上除了完成基本功能實(shí)現(xiàn)外,還必須包括與系統(tǒng)配置和異常處理相關(guān)的初始化配置和錯誤處理等模塊設(shè)計,通常在主控模塊中被調(diào)用。
初始化配置模塊使軟件模塊在執(zhí)行基本功能之前處于就緒狀態(tài)。初始化配置包括配置文件調(diào)用、現(xiàn)場產(chǎn)生兩種配置模式。配置文件的使用屬于靜態(tài)配置,適用于諸如設(shè)備參加字配置、設(shè)備合作目標(biāo)配置、方案預(yù)設(shè)、目標(biāo)參數(shù)設(shè)置等事前已知但隨任務(wù)型號和發(fā)次變化的配置項;現(xiàn)場產(chǎn)生屬于動態(tài)配置,適用于諸如作業(yè)啟動項配置、加載模塊配置等需要在系統(tǒng)運(yùn)行中根據(jù)需求動態(tài)調(diào)整的配置項。
錯誤處理模塊是對系統(tǒng)可能出現(xiàn)的各種異常采取的必要保護(hù)措施,為保證系統(tǒng)的穩(wěn)定性和可控性提供技術(shù)支持。如系統(tǒng)初始化的異常處理、線程調(diào)用的異常處理等。
一般主控模塊設(shè)計見圖2中的偽C代碼。
一個進(jìn)程通常是由多個線程組成,每個線程又包含若干功能模塊,系統(tǒng)執(zhí)行不同的作業(yè)時需要不同的模塊參加,協(xié)作運(yùn)行實(shí)現(xiàn)不同的功能[5]。為實(shí)現(xiàn)進(jìn)程內(nèi)不同模塊加載的通用性和靈活性,設(shè)計線程模塊開關(guān),構(gòu)成模塊開關(guān)數(shù)據(jù)結(jié)構(gòu),在每個作業(yè)啟動時更新一次模塊開關(guān)數(shù)據(jù)結(jié)構(gòu)。每個對應(yīng)線程所屬模塊的開關(guān)成員通過邏輯值“真(TRUE)”表示參加/“假(FALSE)”表示不參加“當(dāng)前作業(yè)”運(yùn)行。
線程控制模型設(shè)計見下頁圖3中的偽C代碼。
3.3.1 設(shè)計思想
圖2 一般主控模塊設(shè)計
在軟件運(yùn)行時,為保證實(shí)時性和可靠性,縮短故障恢復(fù)時間,實(shí)時數(shù)據(jù)處理軟件任意任務(wù)程序始終處于1主1備熱備份狀態(tài),即除了運(yùn)行該任務(wù)程序進(jìn)行任務(wù)處理的節(jié)點(diǎn)外,另一節(jié)點(diǎn)同時運(yùn)行該程序,啟動任務(wù)處理,但不輸出處理結(jié)果,構(gòu)成1主1備工作模式。在此過程中,通過心跳線實(shí)時監(jiān)視節(jié)點(diǎn)狀態(tài),發(fā)現(xiàn)節(jié)點(diǎn)故障后立即執(zhí)行任務(wù)遷移和恢復(fù),以縮短任務(wù)遷移和恢復(fù)的響應(yīng)時間,提高系統(tǒng)的實(shí)時性。
3.3.2 任務(wù)分配表的設(shè)計
任務(wù)分配表是主控節(jié)點(diǎn)用于向系統(tǒng)內(nèi)各節(jié)點(diǎn)分配任務(wù),是隨著節(jié)點(diǎn)狀態(tài)變化動態(tài)分配的[6]。任務(wù)分配表結(jié)構(gòu)單元設(shè)計如圖4所示。作業(yè)號表示系統(tǒng)執(zhí)行的作業(yè),用于配置與作業(yè)相關(guān)的執(zhí)行環(huán)境;節(jié)點(diǎn)IP地址是指任務(wù)分配節(jié)點(diǎn)的IP標(biāo)識;目標(biāo)號表示任務(wù)分配節(jié)點(diǎn)處理該任務(wù)的測控目標(biāo)編號;任務(wù)號表示任務(wù)分配節(jié)點(diǎn)處理的任務(wù),如外測任務(wù)、遙測任務(wù)等;熱備類型表示任務(wù)分配節(jié)點(diǎn)上分配的任務(wù)作為主任務(wù)還是備任務(wù)運(yùn)行。
圖3 線程控制模型
圖4 任務(wù)分配表結(jié)構(gòu)單元
3.3.4 故障或異常處理方法
假設(shè)當(dāng)前任務(wù)A的主任務(wù)分配到節(jié)點(diǎn)1上,備任務(wù)分配到節(jié)點(diǎn)2上。
1)主任務(wù)故障時的處理
當(dāng)節(jié)點(diǎn)1上的任務(wù)A(主)發(fā)生故障,并被控制節(jié)點(diǎn)捕獲,處理過程如下:
①控制節(jié)點(diǎn)通過任務(wù)分配表切換節(jié)點(diǎn)2上的任務(wù)A為主任務(wù)類型運(yùn)行。
②如果節(jié)點(diǎn)1是任務(wù)故障,重新啟動該任務(wù),作為備任務(wù)類型運(yùn)行。
③如果節(jié)點(diǎn)1是機(jī)器故障,控制節(jié)點(diǎn)根據(jù)任務(wù)分配策略遷移節(jié)點(diǎn)2上的任務(wù)到其他“活動”節(jié)點(diǎn)并作為備任務(wù)運(yùn)行,如節(jié)點(diǎn)3分配了任務(wù)A的備任務(wù),此時節(jié)點(diǎn)2與節(jié)點(diǎn)3上運(yùn)行的任務(wù)A重新構(gòu)成1主1備熱備份狀態(tài);同時,恢復(fù)故障節(jié)點(diǎn)的狀態(tài)。
2)備任務(wù)故障時的處理
假設(shè)節(jié)點(diǎn)2上的任務(wù)A(備)發(fā)生故障,并被控制節(jié)點(diǎn)捕獲,處理過程如下:
①如果節(jié)點(diǎn)2是任務(wù)故障,重新啟動該任務(wù);
②如果節(jié)點(diǎn)2是機(jī)器故障,控制節(jié)點(diǎn)根據(jù)任務(wù)分配策略遷移節(jié)點(diǎn)2上的任務(wù)到其他“活動”節(jié)點(diǎn),如節(jié)點(diǎn)3分配了任務(wù)A的備任務(wù),此時節(jié)點(diǎn)1與節(jié)點(diǎn)3上運(yùn)行的任務(wù)A重新構(gòu)成1主1備熱備份狀態(tài);同時,恢復(fù)故障節(jié)點(diǎn)的狀態(tài)。
3)主備任務(wù)同時故障的處理
假設(shè)節(jié)點(diǎn)1上的任務(wù)A(主)和節(jié)點(diǎn)2上的任務(wù)A(備)出現(xiàn)故障,并被控制節(jié)點(diǎn)捕獲,處理過程如下:
①如果節(jié)點(diǎn)同為機(jī)器故障,在其他“活動”節(jié)點(diǎn)上根據(jù)任務(wù)分配策略重新構(gòu)成1主1備熱備份狀態(tài);同時,恢復(fù)故障節(jié)點(diǎn)的狀態(tài)。
②如果節(jié)點(diǎn)同為任務(wù)故障,則同時重啟節(jié)點(diǎn)1和節(jié)點(diǎn)2上的任務(wù),構(gòu)成1主1備。
③如果1個節(jié)點(diǎn)為機(jī)器故障,1個節(jié)點(diǎn)是任務(wù)故障,則將任務(wù)故障節(jié)點(diǎn)重啟為主任務(wù),根據(jù)任務(wù)分配策略在其他“活動”節(jié)點(diǎn)上重新找一個節(jié)點(diǎn)啟動備任務(wù),構(gòu)成1主1備熱備份狀態(tài);同時,恢復(fù)故障節(jié)點(diǎn)的狀態(tài)。
4)故障節(jié)點(diǎn)恢復(fù)時的處理
節(jié)點(diǎn)上的機(jī)器故障恢復(fù)后,向控制節(jié)點(diǎn)發(fā)送狀態(tài)包。控制節(jié)點(diǎn)收到狀態(tài)包后向其發(fā)送整個系統(tǒng)的配置信息、狀態(tài)信息等。
節(jié)點(diǎn)按照配置信息和狀態(tài)信息配置好軟件狀態(tài),重新作為“活動”節(jié)點(diǎn)加入到系統(tǒng)中,準(zhǔn)備就緒,此時控制節(jié)點(diǎn)將根據(jù)任務(wù)分配策略為其重新分配任務(wù)。
實(shí)時數(shù)據(jù)處理常用算法在實(shí)時數(shù)據(jù)處理軟件中被頻繁使用,如果缺少標(biāo)準(zhǔn)算法模型,則是誰使用誰設(shè)計編寫,導(dǎo)致軟件編程人員的重復(fù)性工作較多,增加了工作量和軟件的復(fù)雜度,且軟件的通用性較差[8]。算法模型庫的設(shè)計目的是將實(shí)時數(shù)據(jù)處理常用算法進(jìn)行標(biāo)準(zhǔn)化處理,統(tǒng)一設(shè)計數(shù)據(jù)處理函數(shù),構(gòu)建一套標(biāo)準(zhǔn)接口函數(shù)庫,有利于程序開發(fā)和移植。
實(shí)時數(shù)據(jù)處理軟件中的常用算法主要分以下幾類:
1)矩陣計算;
2)坐標(biāo)系之間的轉(zhuǎn)換;
3)數(shù)據(jù)異常處理及誤差修正;
4)設(shè)備數(shù)據(jù)的定位、求速計算;
5)數(shù)字濾波器。
模型庫的基本組成主要有與常量、數(shù)據(jù)類型和數(shù)據(jù)結(jié)構(gòu)相關(guān)的定義和與算法實(shí)現(xiàn)相關(guān)的函數(shù)。除此之外,為便于編程人員使用,完整的模型庫還應(yīng)包括函數(shù)說明、算法功能注釋等內(nèi)容,這些內(nèi)容雖與模型庫的功能實(shí)現(xiàn)無關(guān),但對模型庫的應(yīng)用者來說非常重要,相當(dāng)于模型庫的聯(lián)機(jī)幫助文檔。
為了提高模型庫的可用性,在設(shè)計時首先需要制定一個好的命名規(guī)則,可以使程序員望名知意,減少注釋的繁瑣。
比較著名的命名規(guī)則是微軟公司的“匈牙利”法,該命名規(guī)則的主要思想是“在變量和函數(shù)名中加入前綴以增進(jìn)人們對程序的理解”?!靶傺览狈ǖ幕驹瓌t是:變量名=屬性+類型+對象描述,其中每一對象的名稱都要求有明確的含義,可以取對象名字全稱或名字的一部分。但“匈牙利”法最大的缺點(diǎn)是煩瑣,如果通篇都采用“匈牙利”法,則會使大多數(shù)程序員無法忍受。在模型庫設(shè)計中,采用命名規(guī)則的目的是標(biāo)準(zhǔn)化接口設(shè)計,因此,對于局部變量的命名,采用絕大多數(shù)編程人員認(rèn)可的共性規(guī)則,如“int i,j,temp;”。對于共用結(jié)構(gòu)變量和函數(shù)的命名,以簡單易用為原則,對“匈牙利”命名規(guī)則做了合理的簡化,制定以下命名規(guī)則。
【規(guī)則1】標(biāo)識符采用英文單詞或其組合,便于記憶和閱讀。
【規(guī)則2】函數(shù)名以m開頭,后接用大寫字母開頭的單詞組合而成。
【規(guī)則3】變量和參數(shù)用小寫字母開頭的單詞組合而成。
【規(guī)則4】結(jié)構(gòu)名以大寫字母開頭的單詞組合而成。
模型庫的設(shè)計主要包括接口設(shè)計和函數(shù)體設(shè)計。
接口設(shè)計對函數(shù)中用到的數(shù)據(jù)結(jié)構(gòu)進(jìn)行標(biāo)準(zhǔn)化設(shè)計,編程實(shí)現(xiàn)時全部采用標(biāo)準(zhǔn)化結(jié)構(gòu)形式調(diào)用,這樣編程人員只需明確接口形式,就可方便地查詢和使用庫函數(shù)。
函數(shù)體設(shè)計即算法的程序?qū)崿F(xiàn)部分,在設(shè)計過程中,對函數(shù)功能進(jìn)行合理劃分,并保證算法的正確性和計算結(jié)果的唯一性。
算法模型庫在正式發(fā)布前需要從正確性、易用性、精度、容錯能力等方面對算法模型進(jìn)行充分驗(yàn)證。通常,模型庫發(fā)布后不需要再作維護(hù)和修改,可供編程人員直接使用。
對于新算法的擴(kuò)充問題,由于模型庫的設(shè)計采用模塊化設(shè)計思想,易于版本升級和功能擴(kuò)展,但對擴(kuò)充的算法模型同樣需要嚴(yán)格開展驗(yàn)證工作,之后以新版本進(jìn)行發(fā)布。
本文基于集群技術(shù)研究了實(shí)時測控數(shù)據(jù)處理軟件的集群軟件結(jié)構(gòu)、通信機(jī)制、控制模型、算法模型庫等關(guān)鍵技術(shù),設(shè)計出實(shí)時測控數(shù)據(jù)處理軟件通用化模型,為提高測控軟件研發(fā)效率,實(shí)現(xiàn)軟件的通用化、易維護(hù)、可擴(kuò)展等特性奠定了技術(shù)基礎(chǔ)。