摘要:對于程序的測量是軟件開發人員必須要重視的一項內容,如何能夠實現自己的程序最優,是每個程序員都追求的目標,該文通過用C語言開發了一個用于程序測量的工具,在Linux環境下測出所開發程序其所占用的CPU時間和內存空間。為程序員開發程序提供了一個用于自檢的工具。
關鍵詞:Linux;C語言;測量;目標程序
中圖分類號:TP316文獻標識碼: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
信息時代的到來,各行各業對計算機都有不同程度的依賴。軟件的出現更是在一定程度上提高了許多行業的工作效率。目前,許多程序員在學習時仍然存在著“無錯就好”的態度,只要代碼沒有錯誤,只要程序能夠運行,就算完成了任務,完全不管程序的運行效率,這樣的程序不但漏洞百出,更是占用了龐大的系統資源。這樣的軟件也跟本無法處理大批量的數據,更不會得到公司或用戶的認可。衡量程序的標準大多是:程序所運行的時間,所消耗的內存,它的健壯性,結構是否合理等。本文從另一個角度設計并實現了一款能夠在Linux操作系統平臺上運行c語言實現的定時測量工具,能夠測出所運行程序占用的CPU時間和內存情況,可以使程序員隨時了解自己所編寫的程序的資源占用情況,使之不斷的優化。
1 程序測量
對于軟件測量,目前還沒有一個被廣泛接受的定義。有人認為:關于測量軟件產生率以便進行比較、成本估計和預報的科學。
軟件度量包括:軟件復雜性度量;模塊性度量;可修行度量;可移植性度量;可擴充性度量;可靠性獨度量;可維護性度量等等。但按照通常的理解,軟件由程序和文檔兩部分組成。那么,軟件復雜性理應比程序復雜性包括更多的內容。但由于文檔的復雜性涉及太多的非技術因素,目前進行的研究還很少,因而在多數文獻里,程序復雜性同軟件復雜性幾乎是同一個概念。所謂軟件復雜性通常指軟件開發工作量與開發費用的多少、周期的長短和軟件內部隱藏錯誤的多少的一種抽象表示。對于軟件或者程序復雜性度量都只把軟件或者程序本身作為度量的對象。就是說,不去考察和度量軟件和程序的執行過程,也不去考察和度量軟件和程序的開發過程。
軟件度量發都可以分為兩種:微觀級度量和宏觀級度量。微觀級度量也稱代碼度量,因為它們是基于代碼的實現細節上的,微觀級度量法集中于度量系統元素的內部機制;宏觀級度量又稱結構度量,因為它們是基于結構設計分析的基礎上,宏觀級度量主要度量系統之間的相互關系。
算法復雜性分析的研究范圍是分析具體算法的執行所需的時間——空間開銷(計算機資源)和它們隨某些參數增長的規律。也就是更側重于對微觀級的度量。一個程序實現了某個算法,怎么樣能夠實現一個很難理解、也很難開發的程序,它所實現的算法的執行占用的空間卻很少或耗費的CPU計算時間最短。
本文基于 Linux 系統的可執行程序定時測量工具實現的是通過運行被測程序測出其所占用的CPU時間和內存。支持延遲測試和并發測試。通常先由用戶選定程序文件,本工具會自動判斷該文件是否存在并且是否為可執行程序文件,如果不是會彈出警告窗口。如果是可執行的程序文件就會添加到表格中。在表格中可以設置需要延遲的時間和是否需要輸入參數。然后用戶就可以點擊“運行”按鈕進行測試了。
2 程序測量的方法及原理
程序的測量主要是對程序性能進行衡量。程序性能(program performance),是指運行一個程序所需要的內存大小和時間。可以采取兩種方法來確定一個程序的性能:一個是分析的方法,一個是實驗的方法。
長期以來,Linux系統一直使用兩種不同的時間值:
1)日歷時間。該值是自1970年1月1日00:00:00以來國際標準時間(UTC)所經過的秒數累計值,這些時間值可用于記錄文件最近一次的修改時間等。系統基本數據類型time_t用于保存這種時間值。
2)進程時間。這也被稱為CPU時間,用以度量進程使用的中央處理機資源。進程時間以時鐘滴答計算,歷史上曾經取每秒為50、60或100個滴答。
系統基本數據類型clock_t用于保存這種時間值。當度量一個進程的時間值時,Linux系統使用三個進程時間值:
·時鐘時間。
·用戶CPU時間
·系統CPU時間
時鐘時間又稱為墻上時鐘時間,它是進程運行的時間總量,其值與系統中同時運行的進程數有關。用戶CPU時間是執行用戶指令所用的時間。系統CPU時間是為該進程執行內核程序經歷的時間。例如,每當一個進程執行一個系統服務時,例如read或write,則在內核內執行該服務所花費的時間就計入該進程的系統CPU時間。用戶CPU時間和系統CPU時間之和常被稱為CPU時間。
內存是Linux內核所管理的最重要的資源之一。因為系統的物理內存總是少于系統所需要的內存數量。虛擬內存就是為了克服這個矛盾而采用的策略。系統的虛擬內存通過在各個進程之間共享內存而使系統看起來有多于實際內存的內存容量。Linux支持虛擬內存,就是使用磁盤作為RAM的擴展,使可用內存相應地有效擴大。核心把當前不用的內存塊存到硬盤,騰出內存給其他目的。當原來的內容又要使用時,再讀回內存。
Linux虛擬內存的實現需要六種機制的支持:地址映射機制、內存分配回收機制、緩存和刷新機制、請求頁機制、交換機制、內存共享機制。
首先內存管理程序通過映射機制把用戶程序的邏輯地址映射到物理地址,在用戶程序運行時如果發現程序中要用的虛地址沒有對應的物理內存時,就發出了請求頁要求;如果有空閑的內存可供分配,就請求分配內存(于是用到了內存的分配和回收),并把正在使用的物理頁記錄在緩存中(使用了緩存機制)。如果沒有足夠的內存可供分配,那么就調用交換機制,騰出一部分內存。另外在地址映射中要通過TLB(翻譯后援存儲器)來尋找物理頁;交換機制中也要用到交換緩存,并且把物理頁內容交換到交換文件中后也要修改頁表來映射文件地址。
磁盤使用量實際也就是文件在磁盤中的占用量,也就是通常所說的文件大小。
在Linux開發中,有很多程序需要在時間和內存上做優化處理,本文是通過用C語言編寫,在Linux環境下能夠對目標程序所運行的時間,及目標程序所消耗的內存兩方面做出測量,能夠方便的對目標程序所消耗的資源加以了解,并及時對目標程序做出改進和優化,使目標程序更加理想化,完美化。
3 測量工具的用法
該工具是在Linux系統下運行,采用Linux的常規程序運行機制,所以簡單易行,它的用法是:“./測量工具名 + 運行模式 ”。本程序的名字為Measurement,運行模式可分為三種,分別是:
1)./Measurement -f 目標文件名//顯示目標程序所消耗的時間(以秒為單位)和內存(以字節為單位)。
2)./Measurement –p -f目標文件名//顯示目標程序所消耗的時間和內存并同時顯示程序的運行結果。
3)./Measurement –t –f 目標文件名//指定延遲時間運行目標程序顯示其所消耗的時間和內存。
4)./Measurement –m 文件名集合//同時顯示多個目標文件所消耗的時間和內存,每個文件名以回車分隔。
4 該工具的執行原理及具體實現
1)從終端輸入“./測量工具名 + 運行模式 ”,即上文所述的4種運行模式。
2)主函數main()從終端讀取參數,如參數符合標準,繼續執行并分析其運行模式,否則,退出。
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)如運行模式為了-m 則執行read_fname(char *filename)函數
void read_fname(char *filename)
{ FILE *fid;
if((fid=fopen(filename,\"r\"))==NULL)
……
fclose(fid);}
讀取每個文件名,在這個過程中用調用char *Trim( char *String )函數進行空格過慮
char *Trim( char *String )
{char*Tail, *Head;
for ( Tail = String + strlen( String ) - 1; Tail >= String; Tail -- )
……
return String;
}
再依次調用run(char *filename,int noecho)計算每個程序的消耗的時間和內存
void run(char *filename,int noecho)
{pid_t pid;
if((pid=fork())<0)
{ perror(\"\Error:\\child fork() error\");
exit(1);}
else if(pid!=0)//父進程
{ int wt1;
waitpid(pid,wt1,0);//等待子進程1結束
…… }
else
{…… }
}
如為 –f ,則直接調用run(char *filename,int noecho)函數進行計算。
4)最后則調用格式化輸出函數void display_format(char *filename,struct rusage usage)進行格式輸出。
5 結束語
從以上討論,我們可以看到C語言程序在Linux系統下的的應用,這里討論的技術有些還是探索性的,還不成熟,在實際的教學和實踐中,可能會遇到許多的問題,如隨著目前計算機多處理器并行計算的日漸普遍,這樣的方式有可能引起極大的錯誤或誤差,所以我們還應該對其進行進一步的研究,將它們應用于實際問題,這樣才能了解它們的實際應用中的有效性及缺陷,對該程序不斷更新。
參考文獻:
[1] Stevens W R,Rago S A.UNIX環境高級編程[M].北京:人民郵電出版社,2006:45-50.
[2] Molay B.Unix/Linux編程實踐教程[M].北京:清華大學大學出版社,2004(10):275-280.
[3] 王柏盛.C語言程序設計[M].北京:高等教育出版社,2004.
[4] 博韋.深入理解Linux內核[M].北京:中國電力出版社,2008:88-96.
[5] 韋東山.嵌入式linux應用開發完全手冊[M].北京:人民郵電出版社,2008.