{eval=Array;=+count(Array);}

成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

問答專欄Q & A COLUMN

linux的靜態(tài)鏈接和動態(tài)鏈接程序有什么區(qū)別?

mcterrymcterry 回答0 收藏1
問題描述:鏈接過程一樣嗎?最終生成的可執(zhí)行程序有什么不同呢?
收藏問題

1條回答

ckllj

ckllj

回答于2022-06-28 09:59

恰好之前我寫過一篇文章討論這個(gè)問題,下面摘錄一部分。

動態(tài)鏈接庫和靜態(tài)鏈接庫

使用我們按照之前幾節(jié)配置好的 vim 輸入以下代碼:

// 文件名

t.c

#include <stdio.h>

int main()

{

printf("hello embedTime ");

return 0;

}

這段代碼包含了 stdio 頭文件,調(diào)用了庫函數(shù) printf,所以編譯它肯定會使用鏈接庫。linux 系統(tǒng)有兩種鏈接庫,一種常常被稱為“靜態(tài)鏈接庫(static library)”,還有一種常被稱作“動態(tài)鏈接庫(shared library)”。

動態(tài)鏈接是應(yīng)用非常廣泛的方式。動態(tài)鏈接庫的英文字面意思可以翻譯為“共享的庫”,的確如此,使用動態(tài)鏈接庫的程序在加載時(shí),linux 內(nèi)核會檢查程序用到的庫是否已經(jīng)在內(nèi)存中,如果在,則 linux 內(nèi)核不再重新加載庫,直接就執(zhí)行程序了。所以,多個(gè)程序可以共享一個(gè)庫,這實(shí)際上可以節(jié)約資源。

對于靜態(tài)鏈接庫來說,程序鏈接時(shí)會將其作為程序的一部分,因此最終生成的可執(zhí)行程序相比于動態(tài)鏈接方式,會更大一點(diǎn)。

編譯上面的程序:

# gcc t.c -o shared.out

這條編譯語句使用的是動態(tài)鏈接方式。為 gcc 命令附加 -static 命令,可以以靜態(tài)鏈接方式編譯程序:

# gcc t.c -static -o static.out

現(xiàn)在我們查看一下這兩種鏈接方式生成的可執(zhí)行程序大小對比:

# ls -ahltotal 888Kdrwxr-xr-x 3 root root 4.0K Dec 17 22:40 .drwxr-xr-x 8 root root 4.0K Dec 11 10:28 ..drwxr-xr-x 2 root root 4.0K Dec 17 22:39 his-rwxr-xr-x 1 root root 8.4K Dec 17 22:40 shared.out-rwxr-xr-x 1 root root 857K Dec 17 22:40 static.out-rw-r--r-- 1 root root 76 Dec 17 21:37 t.c

很容易看出,使用靜態(tài)鏈接方式生成的可執(zhí)行程序,要比使用動態(tài)鏈接方式生成的可執(zhí)行程序大 100 多倍。雖然幾百 KB 對于大多數(shù) linux 主機(jī)來說不算什么,但是嵌入式系統(tǒng)資源一般都非常緊缺,這時(shí)再輕易使用靜態(tài)鏈接就非常奢侈了。

使用靜態(tài)鏈接也是有好處的,生成的可執(zhí)行程序能夠脫離庫獨(dú)立運(yùn)行,而使用動態(tài)鏈接的可執(zhí)行程序則不能脫離庫獨(dú)立運(yùn)行。

靜態(tài)鏈接和動態(tài)鏈接的可執(zhí)行程序,執(zhí)行過程有哪些不同

上面討論了 linux 中程序鏈接的兩種方式,既然可執(zhí)行程序體積相差這么多,那它們的執(zhí)行過程也應(yīng)該有所差異了?的確如此,現(xiàn)在我們一起來分析下。在linux中分析程序的執(zhí)行過程,可以使用 strace 命令。

先分析 shared.out,我們輸入 strace ./shared.out,會發(fā)現(xiàn)有一大堆輸出信息:

# strace ./shared.outexecve("./shared.out", ["./shared.out"], [/* 22 vars */]) = 0brk(0) = 0x1a66000access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3fstat(3, {st_mode=S_IFREG|0644, st_size=33518, ...}) = 0mmap(NULL, 33518, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7fe241ff2000close(3) = 0access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3read(3, "ELF>P "..., 832) = 832fstat(3, {st_mode=S_IFREG|0755, st_size=1857312, ...}) = 0mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe241ff1000mmap(NULL, 3965632, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fe241a10000mprotect(0x7fe241bce000, 2097152, PROT_NONE) = 0mmap(0x7fe241dce000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1be000) = 0x7fe241dce000mmap(0x7fe241dd4000, 17088, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fe241dd4000close(3) = 0mmap(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe241fef000arch_prctl(ARCH_SET_FS, 0x7fe241fef740) = 0mprotect(0x7fe241dce000, 16384, PROT_READ) = 0mprotect(0x600000, 4096, PROT_READ) = 0mprotect(0x7fe241ffb000, 4096, PROT_READ) = 0munmap(0x7fe241ff2000, 33518) = 0fstat(1, {st_mode=S_IFCHR|0600, st_rdev=makedev(136, 2), ...}) = 0mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fe241ffa000write(1, "hello embedTime ", 16hello embedTime) = 16exit_group(0) = ?+++ exited with 0 +++

這些輸出信息即為 linux 執(zhí)行程序的過程。每一個(gè)函數(shù),都可以通過 man 命令查詢其手冊。幾個(gè)主要的過程如下:

就是加載庫到內(nèi)存,再執(zhí)行程序,最后調(diào)用系統(tǒng)調(diào)用 exit 結(jié)束程序。

現(xiàn)在再來看看靜態(tài)鏈接的程序 static.out,同樣使用 strace 命令查看:

# strace static.out

可以看出,因?yàn)殒溄訒r(shí),編譯器直接把靜態(tài)庫作為程序的一部分了,所以這里相比于動態(tài)鏈接的程序,少了很多將庫映射到內(nèi)存的操作:

到這里,動態(tài)鏈接和靜態(tài)鏈接程序執(zhí)行時(shí)的不同點(diǎn),就清楚了。

歡迎在評論區(qū)一起討論,質(zhì)疑。文章都是手打原創(chuàng),每天最淺顯的介紹C語言、linux等嵌入式開發(fā),喜歡我的文章就關(guān)注一波吧,可以看到最新更新和之前的文章哦。

評論0 贊同0
  •  加載中...

最新活動

您已邀請0人回答 查看邀請

我的邀請列表

  • 擅長該話題
  • 回答過該話題
  • 我關(guān)注的人
向幫助了您的網(wǎng)友說句感謝的話吧!
付費(fèi)偷看金額在0.1-10元之間
<