齊文軍
(91550部隊(duì) 大連 116021)
實(shí)時控制軟件通常是一個多任務(wù)、多作業(yè)的實(shí)時系統(tǒng),通常采用共享內(nèi)存區(qū)、消息隊(duì)列、信號燈等技術(shù)實(shí)現(xiàn)進(jìn)程間通信[1~2],已有文獻(xiàn)對進(jìn)程間通信機(jī)制進(jìn)行比較分析[3]以及對進(jìn)程間信號通信機(jī)制進(jìn)行分析[4],上述研究雖然能夠?qū)崿F(xiàn)進(jìn)程間信息的傳遞和共享,但缺少一種在任何時刻都能夠?qū)崟r地知道當(dāng)前執(zhí)行什么任務(wù),什么作業(yè),何時執(zhí)行等命令以及中斷信號何時到達(dá)等信息的聰明機(jī)制。本文根據(jù)Tru64 UNIX操作系統(tǒng)中實(shí)時信號的功能特性,建立一種在實(shí)時控制軟件中進(jìn)程間實(shí)時傳遞信息的聰明的通信機(jī)制。
信號是進(jìn)程間通信機(jī)制中唯一的異步通信機(jī)制。信號機(jī)制主要用于產(chǎn)生、傳送和處理系統(tǒng)中的各種信號。信號的建立、傳送和處理都是由軟件實(shí)現(xiàn)的,因此信號也稱為軟中斷,信號機(jī)制又稱為軟中斷機(jī)制。根據(jù)實(shí)時應(yīng)用的特點(diǎn),Tru64UNIX操作系統(tǒng)在實(shí)時接口庫中引入了軟中斷機(jī)制,利用信號的異步特性來實(shí)現(xiàn)進(jìn)程間的實(shí)時通信,為實(shí)時軟件的設(shè)計提供了強(qiáng)有力的支持。
Tru64UNIX操作系統(tǒng)中,POSIX 1003.1b實(shí)時接口庫強(qiáng)化了實(shí)時信號功能,為實(shí)時應(yīng)用程序靈活運(yùn)用實(shí)時信號創(chuàng)造了條件,其不僅增加了用戶可定義的實(shí)時信號數(shù)量,在向進(jìn)程發(fā)信號時,建立了信號排隊(duì)機(jī)制,使得同一信號的多次發(fā)送可以加以區(qū)分,不會造成信號丟失,使進(jìn)程能夠更快地響應(yīng)實(shí)時信號的發(fā)送,并提供了向進(jìn)程發(fā)送實(shí)時信號的同時,傳送該信號的附加信息功能。
為了分析實(shí)時信號的傳遞機(jī)制,首先要了解具有多線程的進(jìn)程地址空間的分配形式,如圖1所示。
圖1 具有多線程的進(jìn)程地址空間的分配形式
從圖1我們可以看出:1)系統(tǒng)資源是分配給進(jìn)程的,而不是分配給線程的;2)每一個線程都有自己的寄存器和棧;3)線程共享進(jìn)程資源。
每個進(jìn)程都有與每個信號相關(guān)的信號屏蔽字,由此屏蔽字來決定哪些信號可以傳遞給該進(jìn)程,而哪些信號在傳遞時將會被阻塞。信號屏蔽字具有繼承性,也就是說,當(dāng)父進(jìn)程調(diào)用fork函數(shù)派生子進(jìn)程時,子進(jìn)程將繼承父進(jìn)程的信號屏蔽字。信號屏蔽字的每一位代表一個信號,在進(jìn)程中把信號屏蔽字中的哪一位設(shè)置為“1”,說明此屏蔽字所對應(yīng)的信號可以傳遞給該進(jìn)程。在設(shè)置信號屏蔽字之前必須先清空信號所在的信號集,否則,將出現(xiàn)段訪問錯誤。因此,與每一個信號相關(guān)的信號屏蔽字是分配給進(jìn)程的系統(tǒng)資源,而不是分配給線程的,進(jìn)程中的所有線程共享與每一個信號相關(guān)的信號屏蔽字。
在實(shí)際應(yīng)用中,經(jīng)過測試表明對如何利用實(shí)時信號來實(shí)現(xiàn)進(jìn)程間同步通信、以及進(jìn)程中多線程間同步通信有如下結(jié)論:
1)只能在主線程中定義、初始化和設(shè)置信號屏蔽字。否則,在利用多線程來接收信號時,如果有兩個或兩個以上的實(shí)時信號同時或相隔時間很短到達(dá)時,進(jìn)程就會終止,并會在終端上顯示收到的實(shí)時信號。
2)如果是利用實(shí)時信號實(shí)現(xiàn)進(jìn)程間的同步通信,除了發(fā)送隊(duì)列中信號排隊(duì)個數(shù)和1)中的限制之外,沒有其它限制。
Tru64Unix操作系統(tǒng)中的POSIX 1003.1b實(shí)時擴(kuò)充程序設(shè)計接口提供了一個新的sigqueue函數(shù),用來實(shí)現(xiàn)向指定進(jìn)程發(fā)送一個帶有可選數(shù)據(jù)的實(shí)時信號的功能。該函數(shù)定義在signal.h頭文件中,函數(shù)原型為int sigqueue(pid_t pid,int signal,union sigval sval);其中,pid是接收signal信號的接收進(jìn)程;signal是發(fā)送進(jìn)程所發(fā)送的實(shí)時信號;sval就是隨信號所傳遞的附加信息,附加信息數(shù)據(jù)結(jié)構(gòu)為
當(dāng)傳遞的信息為整型時使用sival_int變量,傳遞的信息為指針類型時使用sival_ptr變量。這樣,就可以針對該函數(shù)的這一特點(diǎn),通過傳遞整型或指針型的信息來實(shí)現(xiàn)進(jìn)程間的信息傳遞。
在利用fork函數(shù)派生子進(jìn)程的時候,若沒有使用exec族函數(shù)調(diào)用其它進(jìn)程的映像來覆蓋此子進(jìn)程的映像,那么父子進(jìn)程之間傳遞附加信息不僅可以是整數(shù)類型的而且也可以是指針類型的;若使用exec族函數(shù)調(diào)用其它進(jìn)程的映像來覆蓋此子進(jìn)程的映像,那么父子進(jìn)程之間傳遞的附加信息只能是整數(shù)類型的。
原因是每一個進(jìn)程都有自己的信號堆棧區(qū),可以用來傳遞信號所附加的指針信息。在利用fork函數(shù)派生子進(jìn)程的時候,子進(jìn)程復(fù)制了父進(jìn)程的信號堆棧區(qū)。若沒有利用exec族函數(shù)調(diào)用其它進(jìn)程的映像來覆蓋此子進(jìn)程的映像,此時父子進(jìn)程具有相同的信號堆棧區(qū),用來傳遞信號所附加的指針指向相同的地址空間,因此能在父子進(jìn)程中傳遞指針類型的信息。如果利用exec族函數(shù)調(diào)用其它進(jìn)程的映像來覆蓋此子進(jìn)程的映像,當(dāng)然信號區(qū)也被覆蓋。此時父子進(jìn)程信號堆棧區(qū)不同,當(dāng)然傳遞附加信息的指針地址也無法確定,因此就無法傳遞附加的指針信息,只能傳遞整數(shù)類型的附加信息。經(jīng)上述分析可知,在上述兩種情況下進(jìn)程間都能傳遞整數(shù)類型的附加信息,而傳遞指針型附加信息是有限制的。
根據(jù)實(shí)時控制軟件進(jìn)程間通信的特點(diǎn)和需求結(jié)合實(shí)時信號的功能特性,既可以利用不同的信號實(shí)現(xiàn)進(jìn)程間通信,也可以利用同一個信號,通過設(shè)置不同的附加信息來實(shí)現(xiàn)進(jìn)程間的通信。本文以整型的附加信息為例簡單說明實(shí)時信號在實(shí)時控制軟件中的應(yīng)用。
在一個Tru64UNIX操作系統(tǒng)[7~8]中的多進(jìn)程實(shí)時應(yīng)用系統(tǒng)中,假定進(jìn)程PID1和PID2向進(jìn)程PID3發(fā)送實(shí)時信號和附加信息。進(jìn)程PID1需要向進(jìn)程PID3發(fā)送的實(shí)時信號為SIGNAL 1_3(信號值假定為SIGRTMIN+2),隨該信號傳遞的附加信息表示PID1進(jìn)程的某個事件產(chǎn)生了。而進(jìn)程PID2需要向進(jìn)程PID3發(fā)送的實(shí)時信號為SIGNAL 2_3(信號值假定為SIGRTMIN+3),隨該信號傳遞的附加信息表示PID2進(jìn)程的某個事件產(chǎn)生了。信號附加信息定義如圖2所示:
圖2 信號附加信息定義表
通過圖2中附加信息定義,當(dāng)PID1進(jìn)程接收到實(shí)時信號SIGNAL 1_3后,根據(jù)附加信息sval.sival_int的值就可以判斷出PID1進(jìn)程中哪一個子信號產(chǎn)生了,進(jìn)而轉(zhuǎn)向SIGNAL1_3不同的信號處理程序。當(dāng)PID3進(jìn)程接收到實(shí)時信號SIGNAL2_3后,根據(jù)附加信息sval.sival_int的值就可以判斷出PID2進(jìn)程中哪一個控制信號產(chǎn)生了,進(jìn)而轉(zhuǎn)向SIGNAL2_3不同的信號處理程序。
3.1.1 進(jìn)程PID1發(fā)送信號
在信號發(fā)送進(jìn)程PID1中,PID1利用sigqueue函數(shù)向進(jìn)程PID3發(fā)送實(shí)時信號SIGNAL1_3。unistd.h頭文件必須放在所有代碼之前,否則會影響實(shí)時性[9~10],其主要代碼如下:
3.1.2 進(jìn)程PID2發(fā)送信號
在信號發(fā)送進(jìn)程PID2中,PID2利用sigqueue函數(shù)向進(jìn)程PID3發(fā)送實(shí)時信號SIGNAL2_3。unistd.h頭文件必須放在所有代碼之前,否則會影響實(shí)時性,其主要代碼如下:
信號接收進(jìn)程PID3進(jìn)程使用POSIX 1003.1b定義的sigwaitinfo或sigtimedwait函數(shù)來接收PID1和PID2進(jìn)程傳來的信號,本文以sigwaitinfo為例接收實(shí)時信號,其函數(shù)原型為
其中,sigset是PID3進(jìn)程所定義的接收信號集,內(nèi)容包含PID1和PID2進(jìn)程向PID3進(jìn)程發(fā)送的實(shí)時信號SIG1_3和SIG2_3,是通過sigaddset函數(shù)增加的。info是存放接收的PID1和PID2進(jìn)程傳過來的信息,該變量是一個結(jié)構(gòu),其中的一個成員為union sigval si_value,si_value同前面講述的sigqueue函數(shù)的第3個參數(shù)是一樣的,PID1和PID2進(jìn)程傳過來的附加信息就存放在此變量中。
假設(shè)PID3進(jìn)程所定義的接收信號集為sigset_recv_pid1,存放信息的變量為info_recv,則PID3進(jìn)程接收PID1和PID2進(jìn)程傳來信號,其主要代碼如下:
為了驗(yàn)證實(shí)時信號在實(shí)時控制軟件中的實(shí)時性和可靠性,在測試平臺(Tru64UNIX操作系統(tǒng),1024M 內(nèi)存,667MHz CPU兩個)上對實(shí)時信號和其他進(jìn)行進(jìn)程間通訊技術(shù)(如管道、消息隊(duì)列、共享內(nèi)存),以20HZ的頻率在進(jìn)程間都傳遞4個字節(jié)信息和信號燈是采用給共享區(qū)中計數(shù)器加1的方法進(jìn)行48小時測試。測試表明,利用這些進(jìn)程間通信技術(shù)進(jìn)行通信沒有發(fā)現(xiàn)數(shù)據(jù)或信號丟失現(xiàn)象,表明這些技術(shù)都是可靠的,在延遲上其測試結(jié)果如下:
表1 測試結(jié)果統(tǒng)計表(單位:μs)
從表1可以看出,直接從共享區(qū)讀寫數(shù)據(jù)是最快的,但是為了防止從共享區(qū)讀出臟數(shù)據(jù),一般需要添加有名信號燈等互斥鎖來保證進(jìn)程間數(shù)據(jù)同步,但其缺少一種靈敏機(jī)制,就是無法實(shí)時知道何時數(shù)據(jù)寫入或讀出;使用實(shí)時信號不僅提供了一種靈敏機(jī)制,而且其實(shí)時行為是有保證的,因此傳遞小信息量的數(shù)據(jù),實(shí)時信號無疑是最佳選擇。
實(shí)際應(yīng)用表明利用實(shí)時信號的功能特性為實(shí)時控制軟件設(shè)計的進(jìn)程間通信的聰明機(jī)制,與其它進(jìn)程間通信技術(shù)相比,不僅方法簡單方便,而且更加安全可靠,系統(tǒng)的實(shí)時性也得到了進(jìn)一步加強(qiáng),在實(shí)時軟件設(shè)計中具有廣泛的實(shí)用價值。實(shí)際應(yīng)用中還可以使用信號與其它進(jìn)程間通信技術(shù)相結(jié)合的方法進(jìn)行信息的傳遞,增加進(jìn)程間通信的靈活性和實(shí)時性。
[1]鄭宗漢.實(shí)時系統(tǒng)軟件基礎(chǔ)[M].北京:清華大學(xué)出版社,2002:3560.
[2]寇欣宇,王仲,葉聲華.基于多進(jìn)程的測控系統(tǒng)軟件設(shè)計及其數(shù)據(jù)通信[J].計算機(jī)工程與應(yīng)用,2000,36(06):101103.
[3]李小群.進(jìn)程間通信機(jī)制的分析與比較[J].計算機(jī)科學(xué),2002,29(11):5861.
[4]王文義.Linux中進(jìn)程間信號通信機(jī)制的分析及其應(yīng)用[J].計算機(jī)工程與應(yīng)用,2005,41(03):8587.
[5]W.Richard Stevens.UNIX網(wǎng)絡(luò)編程 第2卷:進(jìn)程間通信[M].北京:清華大學(xué)出版社,2000:240300.
[6]唐靖飚.UNIX平臺下C語言高級編程指南[M].北京:中國宇航出版社,2000:3570.
[7]Butenhof,D.R.Programming with POSIX Threads[M].AddisonWesley,1997:200215.
[8]Maurice J.Bach.The Design of the UNIX Operating System[M].Prentice Hall PTR,2000.113131.
[9]Tru64UNIX Compaq C Language Reference Manual[M].Compaq Computer Corporation.August,2000:185190.
[10]Tru64UNIX Guide to the POSIX Threads Library[M].Compaq Computer Corporation,2000:150161.