国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > linux開發(fā):linux內(nèi)存加載動態(tài)庫?

linux開發(fā):linux內(nèi)存加載動態(tài)庫? 時間:2019-03-27      來源:華清遠見

1 Linux應用程序可能會使用到兩種函數(shù)庫,一種靜態(tài)庫、一種動態(tài)庫,靜態(tài)庫以.a為擴展名,動態(tài)庫以.so為擴展名。二者都使用廣泛。

2 動態(tài)庫和靜態(tài)庫的基本概念?

靜態(tài)庫,是在可執(zhí)行程序連接時就已經(jīng)加入到執(zhí)行碼中,在物理上成為執(zhí)行程序的一部分;使用靜態(tài)庫編譯的程序運行時無需該庫文件支持,哪里都可以用,但是生成的可執(zhí)行文件較大。動態(tài)庫,是在可執(zhí)行程序啟動時加載到執(zhí)行程序中,可以被多個可執(zhí)行程序共享使用。使用動態(tài)庫編譯生成的程序相對較小,但運行時需要庫文件支持,如果機器里沒有這些庫文件就不能運行。

3 如何使用動態(tài)庫?

動態(tài)庫也叫共享庫,如果在程序連接時使用共享庫,就必須在運行時找到共享庫的位置。Linux的可執(zhí)行程序在執(zhí)行的時候默認是先搜索/lib和/usr/lib這兩個目錄,然后按照/etc/ld.so.conf里面的配置搜索絕對路徑。同時,linux也提供了環(huán)境變量LD_LIBRARY_PATH供用戶選擇使用,用戶可以通過它來查找默認路徑之外的其他路徑,如要查找/work/lib路徑,你可以在/etc/rc.d/rc.local或其他系統(tǒng)啟動后即可執(zhí)行到的腳本文件中添加如下語句:LD_LIBRARY_PATH=/work/lib:$(LD_LIBRARY_PATH)。并且LD_LIBRARY_PATH路徑優(yōu)先于系統(tǒng)默認路徑之前查找。

不過LD_LIBRARY_PATH的設定作用是全局的,過多的使用可能會影響到其他應用程序的運行,所以多用在調(diào)試。

4 庫的連接路經(jīng)和運行路經(jīng)

現(xiàn)代連接器在處理動態(tài)庫時將鏈接時路徑(Link-time path)和運行時路徑(Run-time path)分開,用戶可以通過-L指定連接時庫的路徑,通過-R(或-rpath)指定程序運行時庫的路徑,大大提高了庫應用的靈活性。比如我們做嵌入式移植時#arm-linux-gcc $(CFLAGS) –o target –L/work/lib/zlib/ -llibz-1.2.3 (work/lib/zlib下是交叉編譯好的zlib庫),將target編譯好后我們只要把zlib庫拷貝到開發(fā)板的系統(tǒng)默認路徑下即可。或者通過- rpath(或-R )、LD_LIBRARY_PATH指定查找路徑

5 動態(tài)庫的加載使用?

基本上每個linux程序都至少會用一個動態(tài)庫,查看某個程序使用了那些動態(tài)庫,使用命令ldd查看

如:#ldd /bin/ls (查看系統(tǒng)中l(wèi)s用到的動態(tài)庫)

#ldd main (查看自定義main用到的動態(tài)庫)

#ldd -u main(查看自定義main中無用的動態(tài)庫)

#strace ./main(查看程序啟動時加載的所有動態(tài)庫)

Linux程序啟動時加載的庫有默認的庫也有顯式手動連接的庫

1 默認:編譯代碼時不手動連接額外庫,那么在代碼中使用到庫函數(shù)時會在運行時自動加載連接需要的庫。

#gcc -o main main.c

#ldd main

linux-vdso.so.1 => (0x00007fffa1b6d000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff4fde52000)

/lib64/ld-linux-x86-64.so.2 (0x00007ff4fe230000)

2 手動:編譯代碼時手動添加額外的庫,那么在程序運行時,既要加載默認的庫,還要加載手動添加的庫。加載的庫多了,會影響程序啟動的速度。

#gcc -o main1 -lm -lrt main.c (編譯時手動連接數(shù)學庫、線程庫)

#ldd main1

linux-vdso.so.1 => (0x00007fff88770000)

libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f993a0cc000)

/lib64/ld-linux-x86-64.so.2 (0x00007f993a4aa000)

#strace ./main1

從程序運行中可以看出main1運行時即加載了默認庫,也加載了手動指定的庫(在此手動指定的數(shù)學庫、線程庫是代碼不需要的,但在程序運行時也加載了),會影響整個程序的加載速度。

大家知不知道linux從程序(program或對象)變成進程(process或進程),要經(jīng)過哪些步驟呢,簡單的說分三步:

1、fork進程,在內(nèi)核創(chuàng)建進程相關內(nèi)核項,加載進程可執(zhí)行文件;

2、查找依賴的so,一一加載映射虛擬地址

3、初始化程序變量。

可以看到,第二步中dll依賴越多,進程啟動越慢,并且發(fā)布程序的時候,有這些鏈接但沒有使用的so,同樣要一起跟著發(fā)布,否則進程啟動時候,會失敗,找不到對應的so。所以我們不能像上面那樣,把一些毫無意義的so鏈接進來,浪費資源。

6 關于Linux程序連接so有兩種方式:隱式和顯示

所謂顯示就是程序主動調(diào)用dlopen打開相關so;首先,dlopen的so使用ldd是查看不到的。其次,使用dlopen打開的so并不是在進程啟動時候加載映射的,而是當進程運行到調(diào)用dlopen代碼地方才加載該so,也就是說,如果每個進程顯示鏈接a.so;但是如果發(fā)布該程序時候忘記附帶發(fā)布該a.so,程序仍然能夠正常啟動,甚至如果運行邏輯沒有觸發(fā)運行到調(diào)用dlopen函數(shù)代碼地方。該程序還能正常運行,即使沒有a.so. 既然顯示加載這么多優(yōu)點,那么為什么實際生產(chǎn)中很少碼農(nóng)使用它呢, 主要原因還是起使用不是很方便,需要開發(fā)人員多寫不少代碼。所以不被大多數(shù)碼農(nóng)使用,還有一個重要原因應該是能提前發(fā)現(xiàn)錯誤,在部署的時候就能發(fā)現(xiàn)缺少哪些so,而不是等到實際上限運行的時候才發(fā)現(xiàn)缺東少西。

上一篇:嵌入式學習:開源與閉源

下一篇:linuxtrap腳本信號捕獲命令的使用

熱點文章推薦
華清學員就業(yè)榜單
高薪學員經(jīng)驗分享
熱點新聞推薦
前臺專線:010-82525158 企業(yè)培訓洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,京ICP備16055225號-5,京公海網(wǎng)安備11010802025203號

回到頂部