殷錫亮
(哈爾濱僑航通信設(shè)備有限公司,哈爾濱 150028)
現(xiàn)代嵌入式處理器上越來越多的使用Linux操作系統(tǒng)。這不僅由于Linux是免費(fèi)開源的,并有眾多的軟件開發(fā)者共同開發(fā),它也具有實(shí)時(shí)性等特點(diǎn),來滿足嵌入式系統(tǒng)開發(fā)所需的特性。雖然Linux本身就提供很好的內(nèi)存使用機(jī)制,但是由于通信軟件對(duì)內(nèi)存使用有其特殊的方式,長(zhǎng)期的直接運(yùn)行于Linux之上會(huì)造成很多的內(nèi)存碎片,造成無(wú)法申請(qǐng)到內(nèi)存。
本文基于Linux操作系統(tǒng)設(shè)計(jì)了一種虛擬軟件平臺(tái),并著重介紹這個(gè)虛擬平臺(tái)提供的內(nèi)存管理機(jī)制。
Linux是一套免費(fèi)使用和自由傳播的類Unix操作系統(tǒng),是一個(gè)基于POSIX和UNIX的多用戶、多任務(wù)、支持多線程和多CPU的操作系統(tǒng)。它能運(yùn)行主要的UNIX工具軟件、應(yīng)用程序和網(wǎng)絡(luò)協(xié)議。它支持32位和64位硬件。Linux繼承了Unix以網(wǎng)絡(luò)為核心的設(shè)計(jì)思想,是一個(gè)性能穩(wěn)定的多用戶網(wǎng)絡(luò)操作系統(tǒng)。
由于Linux具有的眾多特性,通信設(shè)備中越來越多地采用Linux,代替費(fèi)用昂貴的Vx Works操作系統(tǒng)。盡管會(huì)降低一定程度的實(shí)時(shí)性,但由于實(shí)時(shí)業(yè)務(wù)的逐年下降,取而代之的是非實(shí)時(shí)的數(shù)據(jù)業(yè)務(wù),系統(tǒng)對(duì)于實(shí)時(shí)性的依賴程度逐漸降低,這也為使用linux提供了可行性。
通信軟件架構(gòu)一般采用如下圖的軟件架構(gòu)模式。
圖1
虛擬軟件平臺(tái)位于操作系統(tǒng)與上層軟件之間,屏蔽了操作系統(tǒng)的特性,由于其特殊的作用,所以它必須提供諸如TCP/IP通信,進(jìn)程間通信,進(jìn)程調(diào)度,內(nèi)存管理,定時(shí)器管理,狀態(tài)機(jī)等諸多功能,而最為重要的就是內(nèi)存管理。
系統(tǒng)內(nèi)存分為堆內(nèi)存以及棧內(nèi)存,對(duì)于小于2048字節(jié)的內(nèi)存,一般使用的是棧內(nèi)存,這種大小的數(shù)據(jù)區(qū)一般用來傳輸信令數(shù)據(jù),對(duì)于傳輸更大的數(shù)據(jù)塊,需要申請(qǐng)的是堆內(nèi)存。
根據(jù)分析通信系統(tǒng)軟件架構(gòu),大概需要幾種消息類型,它們使用的數(shù)據(jù)長(zhǎng)度大約為128字節(jié),256字節(jié),512字節(jié),1024字節(jié),2 048 字節(jié),4 096字節(jié),8 192字節(jié),16 384字節(jié)等。(如圖2所示)
圖2
在內(nèi)存池的構(gòu)建上,我們也根據(jù)需求,分別向操作系統(tǒng)申請(qǐng)堆內(nèi)存以及棧內(nèi)存。其中小于以及等于2 048字節(jié)的,申請(qǐng)棧內(nèi)存,即靜態(tài)數(shù)據(jù)區(qū)內(nèi)存;對(duì)于大于2 048字節(jié)的,申請(qǐng)堆內(nèi)存,即動(dòng)態(tài)內(nèi)存區(qū)內(nèi)存。但是動(dòng)態(tài)內(nèi)存在內(nèi)存池初始化后對(duì)于操作系統(tǒng)來說,它也變成了靜態(tài)的內(nèi)存,因?yàn)樗械膬?nèi)存申請(qǐng)操作以及回收操作,都是這一片在初始化即申請(qǐng)到的系統(tǒng)內(nèi)存上面進(jìn)行。
根據(jù)業(yè)務(wù)模塊調(diào)用傳進(jìn)的數(shù)據(jù)長(zhǎng)度參數(shù),判斷數(shù)據(jù)長(zhǎng)度是屬于哪一個(gè)數(shù)據(jù)區(qū)間,如果小于64字節(jié),即使用64字節(jié)內(nèi)存池,如果數(shù)據(jù)長(zhǎng)度在64與128之間,則使用128字節(jié)內(nèi)存池,以此類推。
申請(qǐng)到內(nèi)存池的內(nèi)存塊后,內(nèi)存管理模塊,自動(dòng)把它從就緒隊(duì)列移到運(yùn)行隊(duì)列尾,并根據(jù)系統(tǒng)時(shí)間戳,申請(qǐng)串號(hào)(內(nèi)存池行號(hào)以及列號(hào)),申請(qǐng)內(nèi)存進(jìn)程ID,對(duì)內(nèi)存塊標(biāo)注(形成一個(gè)唯一的標(biāo)識(shí)),直到內(nèi)存申請(qǐng)進(jìn)程釋放這片內(nèi)存,內(nèi)存管理模塊根據(jù)申請(qǐng)串號(hào)在運(yùn)行隊(duì)列找到這片內(nèi)存,并把它內(nèi)容清空,放回到就緒隊(duì)列尾。
如果使用內(nèi)存管理模塊的應(yīng)用進(jìn)程為多線程處理,就必須在申請(qǐng)內(nèi)存的操作以及釋放內(nèi)存的操作加入互斥機(jī)制,比如線程鎖,或者信號(hào)的PV操作,等等,用來保護(hù)內(nèi)存管理機(jī)制,使其能夠串行地對(duì)內(nèi)存池進(jìn)行操作。
抑或?yàn)榱嗽黾酉到y(tǒng)的并發(fā)性處理機(jī)制,可以在初始化的時(shí)候明確應(yīng)用進(jìn)程使用幾個(gè)線程,為每個(gè)線程獨(dú)立配備一個(gè)內(nèi)存池,這樣不會(huì)出現(xiàn)競(jìng)爭(zhēng)機(jī)制,加快了系統(tǒng)的運(yùn)行速度。
筆者推薦后一種方法,因?yàn)橥ㄐ跑浖南到y(tǒng)特性,這種處理方法更有利于系統(tǒng)穩(wěn)定的運(yùn)行。
內(nèi)存作為一個(gè)系統(tǒng)軟件運(yùn)行依賴最為重要的資源,需要統(tǒng)一地進(jìn)行分配管理,不能由上層的業(yè)務(wù)模塊自行調(diào)用系統(tǒng)A P I,去直接操作系統(tǒng)內(nèi)存,這樣會(huì)造成內(nèi)存碎片的產(chǎn)生,降低系統(tǒng)的可靠性。
[1] (美)博韋.深入理解 LINUX內(nèi)核[M].陳莉群,馮銳,牛欣源,譯.中國(guó)電力出版社,2008.
[2] [美]洛夫.Linux系統(tǒng)編程[M].東南大學(xué)出版社,2009.
[3] Dharma Prakash AgrawalQing-An Zeng.無(wú)線與移動(dòng)通信系統(tǒng)[M].徐春秀,武穆清,譯.人民郵電出版社,2005.
[4] (美)W.Richard Stevens Stephen A.Rago.UNIX環(huán)境高級(jí)編程[M].尤晉元,張亞英,戚正偉,譯.人民郵電出版社,2008.
[5] 嚴(yán)蔚敏,吳偉民.數(shù)據(jù)結(jié)構(gòu)(C語(yǔ)言)[M].清華大學(xué)出版社,2007.