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

国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

問(wèn)答專(zhuān)欄Q & A COLUMN

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

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

1條回答

ckllj

ckllj

回答于2022-06-28 09:59

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

動(dòng)態(tài)鏈接庫(kù)和靜態(tài)鏈接庫(kù)

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

// 文件名

t.c

#include <stdio.h>

int main()

{

printf("hello embedTime ");

return 0;

}

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

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

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

編譯上面的程序:

# gcc t.c -o shared.out

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

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

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

# 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í)行程序,要比使用動(dòng)態(tài)鏈接方式生成的可執(zhí)行程序大 100 多倍。雖然幾百 KB 對(duì)于大多數(shù) linux 主機(jī)來(lái)說(shuō)不算什么,但是嵌入式系統(tǒng)資源一般都非常緊缺,這時(shí)再輕易使用靜態(tài)鏈接就非常奢侈了。

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

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

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

先分析 shared.out,我們輸入 strace ./shared.out,會(huì)發(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í)行程序的過(guò)程。每一個(gè)函數(shù),都可以通過(guò) man 命令查詢(xún)其手冊(cè)。幾個(gè)主要的過(guò)程如下:

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

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

# strace static.out

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

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

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

評(píng)論0 贊同0
  •  加載中...

最新活動(dòng)

您已邀請(qǐng)0人回答 查看邀請(qǐng)

我的邀請(qǐng)列表

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