摘要:對于程序的測量是軟件開發(fā)人員必須要重視的一項內(nèi)容,如何能夠?qū)崿F(xiàn)自己的程序最優(yōu),是每個程序員都追求的目標(biāo),該文通過用C語言開發(fā)了一個用于程序測量的工具,在Linux環(huán)境下測出所開發(fā)程序其所占用的CPU時間和內(nèi)存空間。為程序員開發(fā)程序提供了一個用于自檢的工具。
關(guān)鍵詞:Linux;C語言;測量;目標(biāo)程序
中圖分類號:TP316文獻(xiàn)標(biāo)識碼:A文章編號:1009-3044(2009)35-10108-02
The Implementation of Procedures Measurement Based on Linux System
XU Yan-jun
(Tonghua Normal University of Asset Management Department,Tonghua 134002,China)
Abstract: For the process measurements are software developers must be an element of attention,how can best achieve their program is the goal pursued by every programmer,this paper by using C language has developed a measurement for program tools in Linux environment,measured by the development process of their occupation of CPU time and memory space.Development process for the programmer provides a tool due to self-test.
Key words: Linux; C language; measurement; object program
信息時代的到來,各行各業(yè)對計算機(jī)都有不同程度的依賴。軟件的出現(xiàn)更是在一定程度上提高了許多行業(yè)的工作效率。目前,許多程序員在學(xué)習(xí)時仍然存在著“無錯就好”的態(tài)度,只要代碼沒有錯誤,只要程序能夠運(yùn)行,就算完成了任務(wù),完全不管程序的運(yùn)行效率,這樣的程序不但漏洞百出,更是占用了龐大的系統(tǒng)資源。這樣的軟件也跟本無法處理大批量的數(shù)據(jù),更不會得到公司或用戶的認(rèn)可。衡量程序的標(biāo)準(zhǔn)大多是:程序所運(yùn)行的時間,所消耗的內(nèi)存,它的健壯性,結(jié)構(gòu)是否合理等。本文從另一個角度設(shè)計并實(shí)現(xiàn)了一款能夠在Linux操作系統(tǒng)平臺上運(yùn)行c語言實(shí)現(xiàn)的定時測量工具,能夠測出所運(yùn)行程序占用的CPU時間和內(nèi)存情況,可以使程序員隨時了解自己所編寫的程序的資源占用情況,使之不斷的優(yōu)化。
1 程序測量
對于軟件測量,目前還沒有一個被廣泛接受的定義。有人認(rèn)為:關(guān)于測量軟件產(chǎn)生率以便進(jìn)行比較、成本估計和預(yù)報的科學(xué)。
軟件度量包括:軟件復(fù)雜性度量;模塊性度量;可修行度量;可移植性度量;可擴(kuò)充性度量;可靠性獨(dú)度量;可維護(hù)性度量等等。但按照通常的理解,軟件由程序和文檔兩部分組成。那么,軟件復(fù)雜性理應(yīng)比程序復(fù)雜性包括更多的內(nèi)容。但由于文檔的復(fù)雜性涉及太多的非技術(shù)因素,目前進(jìn)行的研究還很少,因而在多數(shù)文獻(xiàn)里,程序復(fù)雜性同軟件復(fù)雜性幾乎是同一個概念。所謂軟件復(fù)雜性通常指軟件開發(fā)工作量與開發(fā)費(fèi)用的多少、周期的長短和軟件內(nèi)部隱藏錯誤的多少的一種抽象表示。對于軟件或者程序復(fù)雜性度量都只把軟件或者程序本身作為度量的對象。就是說,不去考察和度量軟件和程序的執(zhí)行過程,也不去考察和度量軟件和程序的開發(fā)過程。
軟件度量發(fā)都可以分為兩種:微觀級度量和宏觀級度量。微觀級度量也稱代碼度量,因?yàn)樗鼈兪腔诖a的實(shí)現(xiàn)細(xì)節(jié)上的,微觀級度量法集中于度量系統(tǒng)元素的內(nèi)部機(jī)制;宏觀級度量又稱結(jié)構(gòu)度量,因?yàn)樗鼈兪腔诮Y(jié)構(gòu)設(shè)計分析的基礎(chǔ)上,宏觀級度量主要度量系統(tǒng)之間的相互關(guān)系。
算法復(fù)雜性分析的研究范圍是分析具體算法的執(zhí)行所需的時間——空間開銷(計算機(jī)資源)和它們隨某些參數(shù)增長的規(guī)律。也就是更側(cè)重于對微觀級的度量。一個程序?qū)崿F(xiàn)了某個算法,怎么樣能夠?qū)崿F(xiàn)一個很難理解、也很難開發(fā)的程序,它所實(shí)現(xiàn)的算法的執(zhí)行占用的空間卻很少或耗費(fèi)的CPU計算時間最短。
本文基于 Linux 系統(tǒng)的可執(zhí)行程序定時測量工具實(shí)現(xiàn)的是通過運(yùn)行被測程序測出其所占用的CPU時間和內(nèi)存。支持延遲測試和并發(fā)測試。通常先由用戶選定程序文件,本工具會自動判斷該文件是否存在并且是否為可執(zhí)行程序文件,如果不是會彈出警告窗口。如果是可執(zhí)行的程序文件就會添加到表格中。在表格中可以設(shè)置需要延遲的時間和是否需要輸入?yún)?shù)。然后用戶就可以點(diǎn)擊“運(yùn)行”按鈕進(jìn)行測試了。
2 程序測量的方法及原理
程序的測量主要是對程序性能進(jìn)行衡量。程序性能(program performance),是指運(yùn)行一個程序所需要的內(nèi)存大小和時間??梢圆扇煞N方法來確定一個程序的性能:一個是分析的方法,一個是實(shí)驗(yàn)的方法。
長期以來,Linux系統(tǒng)一直使用兩種不同的時間值:
1)日歷時間。該值是自1970年1月1日00:00:00以來國際標(biāo)準(zhǔn)時間(UTC)所經(jīng)過的秒數(shù)累計值,這些時間值可用于記錄文件最近一次的修改時間等。系統(tǒng)基本數(shù)據(jù)類型time_t用于保存這種時間值。
2)進(jìn)程時間。這也被稱為CPU時間,用以度量進(jìn)程使用的中央處理機(jī)資源。進(jìn)程時間以時鐘滴答計算,歷史上曾經(jīng)取每秒為50、60或100個滴答。
系統(tǒng)基本數(shù)據(jù)類型clock_t用于保存這種時間值。當(dāng)度量一個進(jìn)程的時間值時,Linux系統(tǒng)使用三個進(jìn)程時間值:
·時鐘時間。
·用戶CPU時間
·系統(tǒng)CPU時間
時鐘時間又稱為墻上時鐘時間,它是進(jìn)程運(yùn)行的時間總量,其值與系統(tǒng)中同時運(yùn)行的進(jìn)程數(shù)有關(guān)。用戶CPU時間是執(zhí)行用戶指令所用的時間。系統(tǒng)CPU時間是為該進(jìn)程執(zhí)行內(nèi)核程序經(jīng)歷的時間。例如,每當(dāng)一個進(jìn)程執(zhí)行一個系統(tǒng)服務(wù)時,例如read或write,則在內(nèi)核內(nèi)執(zhí)行該服務(wù)所花費(fèi)的時間就計入該進(jìn)程的系統(tǒng)CPU時間。用戶CPU時間和系統(tǒng)CPU時間之和常被稱為CPU時間。
內(nèi)存是Linux內(nèi)核所管理的最重要的資源之一。因?yàn)橄到y(tǒng)的物理內(nèi)存總是少于系統(tǒng)所需要的內(nèi)存數(shù)量。虛擬內(nèi)存就是為了克服這個矛盾而采用的策略。系統(tǒng)的虛擬內(nèi)存通過在各個進(jìn)程之間共享內(nèi)存而使系統(tǒng)看起來有多于實(shí)際內(nèi)存的內(nèi)存容量。Linux支持虛擬內(nèi)存,就是使用磁盤作為RAM的擴(kuò)展,使可用內(nèi)存相應(yīng)地有效擴(kuò)大。核心把當(dāng)前不用的內(nèi)存塊存到硬盤,騰出內(nèi)存給其他目的。當(dāng)原來的內(nèi)容又要使用時,再讀回內(nèi)存。
Linux虛擬內(nèi)存的實(shí)現(xiàn)需要六種機(jī)制的支持:地址映射機(jī)制、內(nèi)存分配回收機(jī)制、緩存和刷新機(jī)制、請求頁機(jī)制、交換機(jī)制、內(nèi)存共享機(jī)制。
首先內(nèi)存管理程序通過映射機(jī)制把用戶程序的邏輯地址映射到物理地址,在用戶程序運(yùn)行時如果發(fā)現(xiàn)程序中要用的虛地址沒有對應(yīng)的物理內(nèi)存時,就發(fā)出了請求頁要求;如果有空閑的內(nèi)存可供分配,就請求分配內(nèi)存(于是用到了內(nèi)存的分配和回收),并把正在使用的物理頁記錄在緩存中(使用了緩存機(jī)制)。如果沒有足夠的內(nèi)存可供分配,那么就調(diào)用交換機(jī)制,騰出一部分內(nèi)存。另外在地址映射中要通過TLB(翻譯后援存儲器)來尋找物理頁;交換機(jī)制中也要用到交換緩存,并且把物理頁內(nèi)容交換到交換文件中后也要修改頁表來映射文件地址。
磁盤使用量實(shí)際也就是文件在磁盤中的占用量,也就是通常所說的文件大小。
在Linux開發(fā)中,有很多程序需要在時間和內(nèi)存上做優(yōu)化處理,本文是通過用C語言編寫,在Linux環(huán)境下能夠?qū)δ繕?biāo)程序所運(yùn)行的時間,及目標(biāo)程序所消耗的內(nèi)存兩方面做出測量,能夠方便的對目標(biāo)程序所消耗的資源加以了解,并及時對目標(biāo)程序做出改進(jìn)和優(yōu)化,使目標(biāo)程序更加理想化,完美化。
3 測量工具的用法
該工具是在Linux系統(tǒng)下運(yùn)行,采用Linux的常規(guī)程序運(yùn)行機(jī)制,所以簡單易行,它的用法是:“./測量工具名 + 運(yùn)行模式 ”。本程序的名字為Measurement,運(yùn)行模式可分為三種,分別是:
1)./Measurement -f 目標(biāo)文件名//顯示目標(biāo)程序所消耗的時間(以秒為單位)和內(nèi)存(以字節(jié)為單位)。
2)./Measurement –p -f目標(biāo)文件名//顯示目標(biāo)程序所消耗的時間和內(nèi)存并同時顯示程序的運(yùn)行結(jié)果。
3)./Measurement –t –f 目標(biāo)文件名//指定延遲時間運(yùn)行目標(biāo)程序顯示其所消耗的時間和內(nèi)存。
4)./Measurement –m 文件名集合//同時顯示多個目標(biāo)文件所消耗的時間和內(nèi)存,每個文件名以回車分隔。
4 該工具的執(zhí)行原理及具體實(shí)現(xiàn)
1)從終端輸入“./測量工具名 + 運(yùn)行模式 ”,即上文所述的4種運(yùn)行模式。
2)主函數(shù)main()從終端讀取參數(shù),如參數(shù)符合標(biāo)準(zhǔn),繼續(xù)執(zhí)行并分析其運(yùn)行模式,否則,退出。
if(argc < 2)
{perror(\"\Error:\\no test file\");
exit(1);
}while((c=getopt(argc,argv,OPTSTR))!=-1)
{switch(c)
{
case 'f':
filename=optarg;
break;
……
case '?':
printf(\"unrecognized option:-%c\\",optopt);
} }
3)如運(yùn)行模式為了-m 則執(zhí)行read_fname(char *filename)函數(shù)
void read_fname(char *filename)
{ FILE *fid;
if((fid=fopen(filename,\"r\"))==NULL)
……
fclose(fid);}
讀取每個文件名,在這個過程中用調(diào)用char *Trim( char *String )函數(shù)進(jìn)行空格過慮
char *Trim( char *String )
{char*Tail, *Head;
for ( Tail = String + strlen( String ) - 1; Tail >= String; Tail -- )
……
return String;
}
再依次調(diào)用run(char *filename,int noecho)計算每個程序的消耗的時間和內(nèi)存
void run(char *filename,int noecho)
{pid_t pid;
if((pid=fork())<0)
{ perror(\"\Error:\\child fork() error\");
exit(1);}
else if(pid!=0)//父進(jìn)程
{ int wt1;
waitpid(pid,wt1,0);//等待子進(jìn)程1結(jié)束
…… }
else
{…… }
}
如為 –f ,則直接調(diào)用run(char *filename,int noecho)函數(shù)進(jìn)行計算。
4)最后則調(diào)用格式化輸出函數(shù)void display_format(char *filename,struct rusage usage)進(jìn)行格式輸出。
5 結(jié)束語
從以上討論,我們可以看到C語言程序在Linux系統(tǒng)下的的應(yīng)用,這里討論的技術(shù)有些還是探索性的,還不成熟,在實(shí)際的教學(xué)和實(shí)踐中,可能會遇到許多的問題,如隨著目前計算機(jī)多處理器并行計算的日漸普遍,這樣的方式有可能引起極大的錯誤或誤差,所以我們還應(yīng)該對其進(jìn)行進(jìn)一步的研究,將它們應(yīng)用于實(shí)際問題,這樣才能了解它們的實(shí)際應(yīng)用中的有效性及缺陷,對該程序不斷更新。
參考文獻(xiàn):
[1] Stevens W R,Rago S A.UNIX環(huán)境高級編程[M].北京:人民郵電出版社,2006:45-50.
[2] Molay B.Unix/Linux編程實(shí)踐教程[M].北京:清華大學(xué)大學(xué)出版社,2004(10):275-280.
[3] 王柏盛.C語言程序設(shè)計[M].北京:高等教育出版社,2004.
[4] 博韋.深入理解Linux內(nèi)核[M].北京:中國電力出版社,2008:88-96.
[5] 韋東山.嵌入式linux應(yīng)用開發(fā)完全手冊[M].北京:人民郵電出版社,2008.