UNIX系統(tǒng)開(kāi)發(fā)-靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的建立_第1頁(yè)
UNIX系統(tǒng)開(kāi)發(fā)-靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的建立_第2頁(yè)
UNIX系統(tǒng)開(kāi)發(fā)-靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的建立_第3頁(yè)
UNIX系統(tǒng)開(kāi)發(fā)-靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的建立_第4頁(yè)
全文預(yù)覽已結(jié)束

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、UNIX系統(tǒng)開(kāi)發(fā)靜態(tài)庫(kù)和動(dòng)態(tài)庫(kù)的建立UNIX系統(tǒng)及各種軟件包為開(kāi)發(fā)人員提供了大量的庫(kù)文件。但一般情況下這些庫(kù)文件還不能足以滿(mǎn)足用戶(hù)的所有需求。開(kāi)發(fā)人員大多會(huì)根據(jù)他們自己的開(kāi)發(fā)、研究要求編寫(xiě)出許多函數(shù)。對(duì)于這些函數(shù),如果都用在命令行中指定源文件的方法同調(diào)用它們的的程序鏈接起來(lái),雖然也是可以的,但也有一些缺點(diǎn):對(duì)每一個(gè)調(diào)用了這些函數(shù)的程序,在編譯時(shí)都需要將這些函數(shù)的代碼分別重新編譯,這實(shí)際是對(duì)計(jì)算時(shí)間的大量浪費(fèi)。 一個(gè)文件中通常都不止包含有一個(gè)函數(shù)的定義。使用上述編譯方法將使得大量無(wú)關(guān)函數(shù)的代碼被拷貝到最終的可執(zhí)行文件中,無(wú)端加大對(duì)存儲(chǔ)資源的占用量,使運(yùn)行時(shí)裝載變慢。 維護(hù)上的諸多不便。由于一個(gè)源

2、文件供多個(gè)程序使用,當(dāng)由于某個(gè)程序的需要面對(duì)此源文件進(jìn)行了某種修改時(shí)將引起諸多意想不到的麻煩。等等。 所有這些原因,使得我們想到能否將自己編寫(xiě)的函數(shù)也作成庫(kù)文件供多個(gè)程序調(diào)用,就如同那些標(biāo)準(zhǔn)的庫(kù)函數(shù)那樣。事實(shí)上在UNIX系統(tǒng)中提供了這方面的工具。借助于這些工具我們不光是能將函數(shù)放到靜態(tài)庫(kù),而且能夠?qū)⑵渥鞒蓜?dòng)態(tài)庫(kù)。下面來(lái)看看如何生成靜態(tài)庫(kù)。我們知道靜態(tài)庫(kù)也稱(chēng)檔案庫(kù),在此檔案文件中實(shí)際上是收集了一系列的目標(biāo)文件。這些目標(biāo)文件就是由CC對(duì)函數(shù)的源代碼編譯生成的。因此,靜態(tài)庫(kù)的生成方法實(shí)際上可分成兩步:1.將各函數(shù)代碼所在地源文件編譯成目標(biāo)文件。例如,對(duì)于前面的myfunc.c,可以用如下命令將其編譯

3、成目標(biāo)文件:$ cc -c myfunc.c當(dāng)然在有多個(gè)源文件時(shí),只需在cc命令行中將其分別列上就可以了。經(jīng)此一步我們將能夠得到各源文件的目標(biāo)文件。對(duì)上例將得到myfunc.o。2.將各目標(biāo)文件收集起來(lái)放到一個(gè)靜態(tài)庫(kù)文件中。這主要借助于ar命令完成,如:$ ar r $HOME/lib/libtest.a myfunc.oar:creating /home/yxz/libtest.a$這里-o $HOME/lib/libtest.a是生成的靜態(tài)庫(kù)的全路徑名。其中我們假定$HOME/lib目錄已經(jīng)存在。注意對(duì)靜態(tài)庫(kù)的命名要遵循libx.a的原則,便于以后能夠在cc命令行中用-l選項(xiàng)指定之。后面的

4、myfunc.o則是待收集到檔案庫(kù)中的目標(biāo)文件名。有多個(gè)目標(biāo)文件時(shí)只需分別列上即可。這生成了libtest.a檔案庫(kù)之后,再編譯myprog.c時(shí),便可使用下面的辦法:$ cc -L $HOME/lib -o myprog myprog.c -ltest這里-L選項(xiàng)指示鏈接程序在$HOME/lib目錄下去搜索有關(guān)的庫(kù)文件(當(dāng)然它還會(huì)自動(dòng)搜索標(biāo)準(zhǔn)位置)。下一節(jié)我們對(duì)此將進(jìn)行更詳細(xì)的說(shuō)明。最后的-ltest選項(xiàng)指示鏈接程序在libtest.so或libtest.a中取搜索myprog.c中對(duì)TestInput()的引用。當(dāng)然由于我們并沒(méi)有生成libtest.so文件,故鏈接程序?qū)⒅荒芩阉鱨ibte

5、st.a。另外,由于我們?cè)诿钚兄胁⑽粗付?dn選項(xiàng),故對(duì)于缺省的-lc選項(xiàng),鏈接程序?qū)⑺阉鱨ibc.so而不是libc.a。靜態(tài)鏈接庫(kù)的生成雖然比較簡(jiǎn)單,但此種鏈接方式也正因?yàn)槠浜?jiǎn)單而在某些情況下達(dá)不到比較高的效率。同動(dòng)態(tài)鏈接方式相比,這種鏈接方式具有如下一些明顯的不足:由于在生成的可執(zhí)行文件中包含有函數(shù)代碼的單獨(dú)拷貝,這些重復(fù)的代碼會(huì)消耗掉大量的磁盤(pán)空間。 運(yùn)行時(shí)各進(jìn)程單獨(dú)在自己的地址空間中裝入它所調(diào)用的每一個(gè)函數(shù)的代碼,這樣在有多個(gè)進(jìn)程都調(diào)用了同一個(gè)函數(shù)時(shí),內(nèi)存中將會(huì)有此函數(shù)代碼的多個(gè)拷貝,無(wú)端地占用比較多的內(nèi)存。 由于對(duì)符號(hào)引用的確定是在編譯鏈接時(shí)完成的。故以后對(duì)函數(shù)的定義進(jìn)行更新的時(shí)

6、候,必須重新鏈接調(diào)用這些函數(shù)的程序。 在虛擬存儲(chǔ)管理方案的基礎(chǔ)上,實(shí)現(xiàn)的動(dòng)態(tài)鏈接方式克服了靜態(tài)鏈接上述不足,而使整個(gè)系統(tǒng)能夠獲得比較高的效率。因此缺省情況下,鏈接程序只要有可能就要試圖進(jìn)行動(dòng)態(tài)鏈接(找?guī)旌瘮?shù)的動(dòng)態(tài)版本)。進(jìn)行動(dòng)態(tài)鏈接的核心問(wèn)題是要生成動(dòng)態(tài)鏈接庫(kù)(共享對(duì)象)。下面我們介紹如何生成動(dòng)態(tài)鏈接庫(kù),然后討論建立動(dòng)態(tài)鏈接庫(kù)的一些原則。建立動(dòng)態(tài)鏈接庫(kù)并不需要用到其他的工具,借助于cc命令即可完成。此時(shí)需在命令行中加上-K PIC和-G這兩個(gè)選項(xiàng),如下我們可以建立libtest的動(dòng)態(tài)版本:$ cc -K PIC -G -o $ HOME/lib/libtest.so myfunc.c這里-o

7、$ HOME/lib/libtest.so指定待生成的動(dòng)態(tài)鏈接庫(kù)的全路徑名。同靜態(tài)庫(kù)一樣,動(dòng)態(tài)庫(kù)的命令應(yīng)遵循libx.so約定。-G選項(xiàng)指示cc按動(dòng)態(tài)鏈接庫(kù)的格式將其各文件的目標(biāo)代碼組織起來(lái)。-K PIC選項(xiàng)是生成動(dòng)態(tài)鏈接庫(kù)所必須的。我們已經(jīng)知道,動(dòng)態(tài)鏈接時(shí)建立在頁(yè)式虛擬管理方式的基礎(chǔ)上的。在這種需存管理方式下,進(jìn)程之間內(nèi)存的共享是以頁(yè)為單位的。只要運(yùn)行時(shí)內(nèi)存頁(yè)不改變,它們就能夠被共享。但是這些共享的頁(yè)在不同的進(jìn)程中??赡軙?huì)具有不同的虛地址。因此這些代碼的物理地址只是在運(yùn)行時(shí)才能得到。(這個(gè)過(guò)程稱(chēng)為地址的重定位。)如果在重定位某個(gè)共享對(duì)象的引用時(shí),某個(gè)進(jìn)程寫(xiě)了一個(gè)共享頁(yè),此時(shí)操作系統(tǒng)將為該進(jìn)程

8、生成改頁(yè)的一個(gè)專(zhuān)用拷貝。這種情況下,頁(yè)面共享的好處就沒(méi)有了。因此程序必須盡可能減少對(duì)頁(yè)面的修改的次數(shù),減少此修改次數(shù)的方法就是使用地址浮動(dòng)的代碼。地址可浮動(dòng)的代碼將能夠被裝入到進(jìn)程地址空間的任何地方。由于此種代碼不依賴(lài)于絕對(duì)地址,故這些代碼將在使用它的每一個(gè)進(jìn)程中在不同的虛地址正確的運(yùn)行,而且在運(yùn)行過(guò)程中是沒(méi)有頁(yè)面修改的。-K PIC選項(xiàng)的作用,就是指示編譯系統(tǒng)生成地址可浮動(dòng)的目標(biāo)文件。此時(shí)在目標(biāo)文件中,可重定位的引用將從所在地正文段被移動(dòng)到數(shù)據(jù)段的表中。在生成了動(dòng)態(tài)庫(kù)之后,就可以在cc命令行中使用它了。如:$ cc -L $ HOME/lib -o myprog myprog.c -l te

9、st這時(shí)雖然在$HOME/lib目錄下也具有test庫(kù)的靜態(tài)版本libtest.a,但鏈接程序?qū)?yōu)先搜索libtest.so。在搞清楚如何生成動(dòng)態(tài)庫(kù)之后,下面我們來(lái)看一看建立動(dòng)態(tài)庫(kù)的一些原則。所有這些原則都是為了性能的改善而提出來(lái)的。性能的改善主要涉及兩方面的問(wèn)題。其一是盡量減少動(dòng)態(tài)鏈接庫(kù)的數(shù)據(jù)段。我們知道,所謂共享,共享的只是代碼。而對(duì)于動(dòng)態(tài)庫(kù)的數(shù)據(jù)段卻是無(wú)法供多個(gè)進(jìn)程共享的。系統(tǒng)將為每個(gè)共享該庫(kù)文件的進(jìn)程都分配該庫(kù)整個(gè)數(shù)據(jù)段的一份內(nèi)存拷貝。因此,要想真正實(shí)現(xiàn)動(dòng)態(tài)鏈接庫(kù)少占用內(nèi)存的目的,必須盡可能地減小共享對(duì)象的數(shù)據(jù)段大小。歸納起來(lái),大致有以下四種方法:(1)盡量使用自動(dòng)(堆棧)變量。如果自

10、動(dòng)變量行的通,就不要使用全局變量或者靜態(tài)變量。(2)盡量使用函數(shù)接口而少使用全局變量進(jìn)行參數(shù)的傳遞。這樣還能夠提高程序的可維護(hù)性。(3)將那些大量使用全局變量的函數(shù)排除在動(dòng)態(tài)鏈接庫(kù)之外。對(duì)于此類(lèi)函數(shù),將其放到靜態(tài)鏈接庫(kù)中比較合適。(4)動(dòng)態(tài)鏈接庫(kù)應(yīng)是自包含的。也就是說(shuō)在生成某個(gè)動(dòng)態(tài)鏈接庫(kù)時(shí),對(duì)其他庫(kù)的函數(shù)調(diào)用不要使用動(dòng)態(tài)鏈接而應(yīng)使用靜態(tài)鏈接。因?yàn)樵诖朔N情況下使用動(dòng)態(tài)鏈接時(shí),調(diào)用該動(dòng)態(tài)庫(kù)中函數(shù)的進(jìn)程將除了得到該動(dòng)態(tài)庫(kù)的數(shù)據(jù)段的拷貝以外,還將得到該數(shù)據(jù)庫(kù)說(shuō)鏈接的其他動(dòng)態(tài)庫(kù)的數(shù)據(jù)段拷貝。這實(shí)際上是得不償失的了。動(dòng)態(tài)鏈接性能的改善所涉及到的第二個(gè)問(wèn)題,盡量減少內(nèi)存頁(yè)面的交換動(dòng)作。雖然使用共享庫(kù)的進(jìn)程并

11、不會(huì)寫(xiě)共享頁(yè)面,但它們?nèi)匀豢赡芤痦?yè)面失效而導(dǎo)致動(dòng)態(tài)鏈接的性能降低。對(duì)這個(gè)問(wèn)題可以使用以下兩種方法加以解決:(1)改進(jìn)對(duì)符號(hào)引用的定位性 這包括兩方面的含義。其一在共享庫(kù)中排除哪些很少用到的、庫(kù)本身不依賴(lài)于它們的那些函數(shù)定義。如果共享庫(kù)中裝有許多不相關(guān)的函數(shù),而且只是一些不相關(guān)的進(jìn)程偶爾調(diào)用這些函數(shù),那么定位性將降低,頁(yè)面的交換將會(huì)變得頻繁。其二是要盡可能把相關(guān)的函數(shù)組合在一起,放到同一個(gè)頁(yè)面中以改進(jìn)引用的定位性。例如:假定func1()調(diào)用了func2()和func3(),并且這三個(gè)函數(shù)的代碼被放到同一頁(yè)中。那么在執(zhí)行func1()的代碼時(shí),func2()和func3()地代碼也將被同時(shí)裝入內(nèi)存。而假如func2()的代碼與func1()的代碼不在同一頁(yè)上。那么在執(zhí)行func1()的過(guò)程中可能還需要去調(diào)頁(yè),從而系統(tǒng)的效率將受到影響。(2)調(diào)整頁(yè)面安排 這主要是指要對(duì)共享庫(kù)的目標(biāo)文件進(jìn)行整理,使那些頻繁使用的函數(shù)的代碼不要越過(guò)頁(yè)邊界被分到不同的頁(yè)上去了。完成這個(gè)工作首先要搞清楚系統(tǒng)內(nèi)存頁(yè)面的大小。然后用nm命令顯示出目標(biāo)文件中各符號(hào)的偏移值。然后據(jù)此可對(duì)各函數(shù)的位置進(jìn)行調(diào)整,使那些必須跨越頁(yè)邊界的是那些使用不太頻繁的函數(shù),以盡

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論