国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫

這篇具有很好參考價值的文章主要介紹了【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

自我名言只有努力,才能追逐夢想,只有努力,才不會欺騙自己。【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
喜歡的點贊,收藏,關注一下把!【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

文件分為:被打開的文件和沒被打開的文件,前面兩篇博文主要講解的是進程與被打開文件的關系。今天這篇博客講的是沒被打開的文件如何在磁盤上存放,文件系統(tǒng)如何管理文件,以及軟硬連接。

1.理解文件系統(tǒng)

問:沒有被打開的文件,該如何被操作系統(tǒng)管理呢?

沒有被打開的文件,只能在磁盤上靜靜的放著,磁盤上有大量的文件,也必須被管理(靜態(tài)管理)起來,方便我們隨時打開。這些工作是由文件系統(tǒng)做的。

在理解文件系統(tǒng)之前,我們必須搞懂磁盤上的文件是怎么存的。
我們似乎還沒有見過磁盤,這里先補充一些磁盤的有關知識。

1.1磁盤的物理結構

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

我們目前很少看見磁盤了,使用最多的就是SSD固定硬盤。

磁盤是我們計算機中唯一的一個機械結構!
磁盤是一個機械結構+外設,所有磁盤訪問速度很慢(相對于CPU和內(nèi)存來說)。

但是在企業(yè)端,磁盤依舊是存儲主流。磁盤具有造價低,存儲量大等特點。。。

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
注意:磁頭和盤面沒有接觸! 距離就像一架波音747在距離地面一米高速飛行。
為什么這樣說呢?因為盤片一秒可以上萬轉(zhuǎn)。
當盤面高速旋轉(zhuǎn)時,磁頭會漂浮起來。

磁盤還需要防止抖動。雖然盤面看起來光滑的,但是表明是存儲數(shù)據(jù)的地方,如果磁盤抖動導致磁頭把盤面刮花就會丟失數(shù)據(jù),就好像以往,看碟片出現(xiàn)花紋情況,就是出現(xiàn)了數(shù)據(jù)丟失。

1.2磁盤的存儲結構

磁盤的存儲是分為那個磁道,那個盤面,那個扇區(qū)的。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

問:磁盤尋址的時候,基本單位是bit,還是byte?

注意,磁盤尋址的時候,基本單位既不是bit,更不是byte,而是一塊塊扇區(qū)。也就是說數(shù)據(jù)都在扇區(qū)放著

每一塊扇區(qū)都是512byte。靠近圓心存儲密度急,遠離圓心密度疏。

如果在單面上,如何定位一個扇區(qū)呢?
首先要確定在那個磁道。
其次確定在對應磁盤的哪一個扇區(qū)。

那如何確定在那個磁道呢?
其實磁頭來回擺動的時候,就是在確定在哪一個磁道。

如何確定在哪一個扇區(qū)?
盤面在高速旋轉(zhuǎn)的時候,就是讓磁頭定位扇區(qū)。

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

一個盤片有兩個盤面,兩個盤面都可以存儲數(shù)據(jù),那另一面怎么存儲數(shù)據(jù)?

有多少盤面就有多少磁頭。并且這些磁頭是共進退的。

那如何在磁盤中,定位任何一個扇區(qū)呢?

1.先定位在哪一個磁道/柱面(因此磁頭是共進退的,磁道一旦確認,所以磁頭就不動了)。
2.在定位哪一個磁頭(也就是確認在哪一個盤面)。
3.最后定位在哪一個扇區(qū)。

磁道(track),柱面(cylinder),磁頭(head),扇區(qū)(sector)。

因此,磁盤中定位任何一個扇區(qū),采用的硬件級別定位方式:CHS定位法!

1.3磁盤的邏輯結構

還記得磁帶嗎?卷起來是圓的,扯出來是線性結構。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
磁盤物理上也是圓形,在邏輯上想象成線性結構。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
假設這個磁盤只有兩個盤片,四個盤面,三個柱面
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

我們把整個磁盤從邏輯上看做一個sector arr[n],把對磁盤的管理,變成對數(shù)組進行管理。

請問現(xiàn)在要找到一個扇區(qū),該如何找到呢?
這時,只需要直到這個扇區(qū)的"下標",就可以定位一個扇區(qū)!

而在操作系統(tǒng)內(nèi)部,稱這種地址為LBA地址(邏輯塊地址)。

假設盤面:4,磁道/柱面:10,扇區(qū):100,扇區(qū)大?。?12byte。
4 * 10 * 100 * 512=總容量(byte)
4 * 10 * 100=下標范圍

在物理層面上磁盤定位一個扇區(qū)采用的是CHS定位法,那么操作系統(tǒng)如何將邏輯上LBA地址(線性地址)轉(zhuǎn)化成CHS對應方案呢?

假設下標123

123/1000=0 —> 0號盤面 H
123/100=1 —> 1號磁道 C
123%100=1 —> 1號扇區(qū) S

操作系統(tǒng)以這樣的算法將LBA地址轉(zhuǎn)化成磁盤能認識的CHS地址,進而訪問磁盤的地址。

為什么OS要進行邏輯抽象呢?直接用CHS不行嗎?

1.便于管理(是管理一個數(shù)組號,還是三維立體結構好呢?)
2.不想讓操作系統(tǒng)代碼和硬件強耦合(如果底層用的是SSD,或者其他硬件存呢?OS只需把LBA轉(zhuǎn)化成其他的就行了)

雖然磁盤的訪問基本單位是512byte,但是依舊很小?。。ㄏ胱x取4KB內(nèi)容需要8次IO)。知道木桶原理就知道,訪問速度根據(jù)最低來進行的。因此OS內(nèi)的文件系統(tǒng)定制的進行多個扇區(qū)的讀取---->1KB,2KB,4KB為基本單位。所以哪怕只想讀取1bit,也必須要將4KB加載到內(nèi)存,進行讀取或者修改,如果有必要再寫回磁盤!

操作系統(tǒng)的文件系統(tǒng)一般默認以4KB大?。ㄒ簿褪?個扇區(qū))為基本單位來進行系統(tǒng)和磁盤IO的過程。

內(nèi)存也是被劃分成為4KB大小的空間被OS進行內(nèi)存管理------頁框
磁盤中的文件尤其是可執(zhí)行文件,按照4KB大小劃分好的塊-----頁幀

把文件加載到內(nèi)存就是把數(shù)據(jù)放到頁框里。

假設磁盤500G,我們看如何存儲文件的。
假設一個磁盤劃分4個盤,C/D/E/F盤,其實就是把整個磁盤劃區(qū)。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
如果能把100G大小空間管理好,直接把辦法對其他區(qū)復制粘貼整個磁盤就可以管理好。

現(xiàn)在對每個區(qū)分組。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

如果我把5G大小空間管理好,對其他分組進行復制粘貼,這100G也能管理好。

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

具體來看看文件系統(tǒng)是如何對空間進行管理的

1.4文件系統(tǒng)

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
Boot Block:分區(qū)的開頭,是分區(qū)表。存放各種分區(qū)的情況,如OS系統(tǒng)在那個分區(qū),圖形化界面在那個區(qū)等。

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
Super Block:保存的整個文件系統(tǒng)的信息,整個分區(qū)有多少分組,起始塊號,結束塊號是多少等等,而且并不是每個分組都有這個Super Block,只存在于一個或者多個分組。

那為什么Super Block不放在分區(qū)而放在分組呢?
這樣做是為了備份。萬一這個文件系統(tǒng)壞掉了,可以把其他分組保存的文件系統(tǒng)的信息拷貝過來,這樣就完成了文件系統(tǒng)的修復。

文件=內(nèi)容+屬性
注意:Linux的文件屬性和文件內(nèi)容是分批存儲的。
文件屬性存儲在Inode,Inode是固定大小,一個文件一個Inode,記錄文件的幾乎所有屬性,但文件名并不在Inode中存儲

文件內(nèi)容存儲在data blocks中,隨著應用類型變化,大小也在變化。

Inode為了進行區(qū)分彼此,每一個I弄得都有自己的ID!

ls -li   //查看Inode編號

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

查找一個文件的時候,統(tǒng)一使用的是Inode編號。

先去Inode Bitmap查看這個位置是否被占用,再去Inode屬性里查找block這個數(shù)組,數(shù)組保存文件內(nèi)容保存在data blocks那些數(shù)據(jù)塊中,
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
下標0-11,直接指向存放數(shù)據(jù)的數(shù)據(jù)塊。
下標12-14,指向的雖然也是一個數(shù)據(jù)塊,但是數(shù)據(jù)塊不光可以保存數(shù)據(jù)也可以保存其他的block id。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
這樣大型文件也可以存儲。

刪除文件也是使用Inode
只需要去把Inode Bitmap把該位置1改成0,就去把Block Bitmap把該位置變成0就好了。

但是在Linux下,我們查找,刪除文件都用的是文件名而不是Inode?。?/strong>
問:目錄是文件嗎?
Linux一切皆文件,因此目錄也是文件。
既然是文件就有自己的Inode和date block,Inode放的是目錄的屬性,那數(shù)據(jù)塊里放的是什么?

其實放的是當前目錄下文件名和Inode的映射關系

因此目錄下創(chuàng)建和刪除文件必須要有寫的權限。

如果有一次誤刪了重要的文件,我該怎么做呢?
最好什么都不要做,如果對其他文件進行了讀寫,Inode會被覆蓋。

想恢復文件怎么做呢?
我們需要知道文件的Inode,去Inode Bitmap把該位置由0變1,然后再去Inode找到數(shù)據(jù)塊的映射關系,根據(jù)映射關系,把Block Bitmap對應的位圖中由0變1,這樣文件內(nèi)容就回來了。

如何知道Inode呢?
我們只知道文件名并不知道Inode,其實OS也考慮到這點,所以OS內(nèi)包含了一個日志信息,當刪除一個文件,OS會把對應刪除的文件與Inode對應關系臨時存儲在日志中,注意這個日志也會有保存時間的。

2.軟硬鏈接

2.1什么是軟硬鏈接

軟鏈接

ln -s myfile.txt soft_file.link

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

硬鏈接

ln myfile.txt hard_file.link

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

對軟硬鏈接發(fā)現(xiàn)了什么?
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

發(fā)現(xiàn)軟鏈接有獨立的Inode,硬鏈接和被鏈接的文件具有相同的Inode。

軟硬鏈接的區(qū)別:是否具有獨立的Inode。

軟鏈接具有獨立的Inode:可以被當作獨立的文件看待。
硬鏈接沒有獨立的Inode,那硬鏈接該如何理解呢?或者建立一個硬鏈接究竟是做了什么?

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
首先知道,建立硬連接根本沒有創(chuàng)建文件!因為沒有給硬鏈接分配獨立的Inode,既然沒有創(chuàng)建文件,那一定沒有自己的屬性集合和內(nèi)容集合,你用的一定是別人的Inode和內(nèi)容。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

這里就回答了:建立硬鏈接就是在指定路徑下,新增文件名和inode的映射關系!

當刪除myfile.txt時,只是將該Inode的映射關系減1。但是Inode還在因此還可以通過hard_file.link與Inode的映射關系找到該文件的內(nèi)容。

那什么時候一個文件算被真正刪除呢?
當一個文件的硬鏈接數(shù)變成0的的時候,這個文件才算真正被刪除!

軟鏈接有自己獨立的Inode和內(nèi)容,當我們刪除myfile.txt,軟鏈接就出錯,但是我們知道Inode還在。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
由此可見軟鏈接內(nèi)容保存的不是與文件Inode的映射關系。

其實軟鏈接里面保存的是與文件所處路徑的映射關系
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
當把文件刪除時,這個映射關系就出錯了。

軟鏈接其實就相當于windows桌面上的快捷方式。

2.2軟硬鏈接的作用

軟鏈接的應用場景:相對于快捷方式,否則執(zhí)行一個進程需要找到該進程所在路徑才能運行進程,而有了軟鏈接直接運行軟鏈接就可以執(zhí)行當前進程。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

unlink soft_file.link //刪除鏈接文件

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

硬鏈接的應用場景:
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

一個普通文件創(chuàng)建,硬鏈接數(shù)為1,而創(chuàng)建目錄硬鏈接數(shù)為2,為什么?

一個普通文件,本身就有一個文件名和自己Inode的映射關系。因此為1;
目錄也是一個文件,具有獨立的Inode,首先就有一個映射關系。這是一個硬鏈接。進入目錄之后發(fā)現(xiàn)
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
.(當前目錄)與新建目錄lesson1的Inode是一樣的。所以當我們執(zhí)行一個進程的時候通常是./a.out其實就相對于lesson1/a.out,(. 也是一個文件名),.就相對于當前目錄lesson1的硬鏈接,因此lesson1的硬鏈接數(shù)為2。

當在lesson1目錄下在創(chuàng)建一個empty目錄,發(fā)現(xiàn)硬鏈接數(shù)由2變成3了。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
這是因為,empty目錄下有一個…(上層目錄),這個文件與lesson1的Inode一樣,相對于又是一個硬鏈接,因此lesson1的硬鏈接數(shù)變成3。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

Linux為什么不允許普通用戶給目錄創(chuàng)建硬鏈接,而可以創(chuàng)建軟鏈接呢?

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
其實.和. .不就是給目錄建立的硬鏈接嘛,不過這是由操作系統(tǒng)自己創(chuàng)建的硬鏈接,OS自己弄不怕出錯,而怕用戶創(chuàng)建硬鏈接出錯。

3.動靜態(tài)庫

關于動靜態(tài)庫的知識,在前面【Liunx】開發(fā)工具第5章節(jié)細說了一些內(nèi)容,這里主要是實現(xiàn)動靜態(tài)庫。

靜態(tài)庫(.a結尾):程序在編譯鏈接的時候把庫的代碼鏈接到可執(zhí)行文件中。程序運行的時候?qū)⒉辉傩枰o態(tài)庫。

動態(tài)庫(.so結尾):程序在運行的時候才去鏈接動態(tài)庫的代碼,多個程序共享使用庫的代碼。

3.1什么是庫

程序在經(jīng)過預處理,編譯,匯編,之后,就要鏈接了,鏈接就是將.o文件和庫鏈接起來形成可執(zhí)行程序。

下面我們將演示類似與庫的思想。

問:如果要寫一個庫需要包含main函數(shù)嗎?

其實并不需要,如果庫里面已經(jīng)幫忙寫好了,那我們在main函數(shù)中寫的代碼有什么用呢?

這里創(chuàng)建main函數(shù),主要為了演示代碼的正確性。
首先建立一些文件,寫簡短的add,sub函數(shù)的實現(xiàn)。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

gcc -c main.c //形成同名的.o文件

.o文件,是重定位目標二進制文件

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
現(xiàn)在三個.c文件都已經(jīng)經(jīng)過預處理,編譯,匯編變成了.o文件。下面就該鏈接了。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
把所有.o文件鏈接起來有兩種方式

gcc -o mymath main.o my_add.o my_sub.o //直接把.o鏈接起來
gcc -o mymatc main.c my_add.c my_sub.c //先把.c文件形成對于的.o文件,再去鏈接

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

當所有.o文件鏈接好了,就形成了可執(zhí)行程序。

假如寫庫的人給不想給用庫的人自己的.c文件,那就給用庫的人提供自己的.o可重定位目標二進制目標文件,讓用庫的人來用自己的代碼來進行鏈接就行了。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

在預處理階段就報錯了,發(fā)現(xiàn)找不到頭文件,因此我們也把頭文件引入。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
這樣編譯就沒報錯了。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
下面將所有.o文件鏈接起來
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
結果是對的。證明編譯是沒問題的。

雖然現(xiàn)在還不懂寫庫,但是未來我可以給對方提供.o文件(方法的實現(xiàn)),.h文件(都有什么方法),然后對方就可以編譯了。------>庫的思想。

.h文件好處理,上面都是沒有經(jīng)過編譯的字符類的,有沒有它能自己看自己查。

但是如果有一萬個.c文件,難道要把這一萬個.c文件都編譯成了.o文件,在加上頭文件一萬個,就有兩萬個文件,就全部直接給用庫的人,那用庫的人在寫命令行的時候是不是太麻煩了。

因此我們可以嘗試將所有的".o文件"打包,給對方提供一個庫文件即可。

庫文件就是多個.o文件打包合并成一個文件,這個文件就是庫,然后打包工具和打包方式的不同就有了動態(tài)庫和靜態(tài)庫。

庫的本質(zhì):就是.o文件的集合。

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

生成靜態(tài)庫

ar -rc libmymath.a my_add.o my_sub.o 

ar是gnu歸檔工具,rc表示(replace and create)

將my_add.o和my_sub.o歸并到libmymath.a。

交付庫=庫文件.a .so+匹配的頭文件都給別人

.PHONY:output
 output:
     mkdir -p mylib/include
     mkdir -p mylib/lib
     cp -f *.a mylib/lib
     cp -f *.h mylib/include   

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
寫好庫之后就可以把庫發(fā)布出去了。

tar czf mylib.tgz mylib //打包

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

然后別人下載,安裝。

cp mylib.tgz ../test  //相當于下載

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

tar xzf mylib.tgz //解壓

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
上面就用cp已經(jīng)tar命令模仿庫的下載的過程。但是還沒有安裝。

安裝的本質(zhì):就是把對應的軟件安裝到特定的目錄下,就是把它對應的可執(zhí)行程序拷貝到指定的系統(tǒng)能夠找到的目錄。

這里先試試不安裝,直接用。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
這里報找不到頭文件的錯誤,但是mylib里面明明就有我的頭文件啊。
其實這是因為,#include"my_add.h" 會在當前路徑下找,但是由于我的庫在mylib目錄下,也就是說不在當前目錄,因此需要指明頭文件在哪。

gcc -o mymath main.c -I./mylib/include //-I指明頭文件

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
報找不到庫在哪

gcc -o mymath main.c -I./mylib/include -L./mylib/lib
//指明頭文件在哪,指明庫在哪

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
但是還是報同樣的錯誤,但這次肯定不是找不到庫在哪里了,那這事因為什么呢?

這是因為,如果要鏈接第三方的庫,必須指明庫的名稱。

但我以前寫代碼的時候,從來沒有指明庫的名稱?。?br> gcc —>C
g++ —>C++
編譯器默認可以識別C,C++自帶的庫。

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
指明了名稱,為什么還有問題?
原因在于,庫名稱不對,
庫名稱:去掉前綴,去掉后綴,剩下的才是庫的名稱。

gcc -o mymath main.c -I./mylib/include -L./mylib/lib -lmymath

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

查看可執(zhí)行程序依賴的動態(tài)庫列表

ldd mytest

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

file mytest

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
發(fā)現(xiàn)我的庫明明是靜態(tài)庫,為什么這里是動態(tài)鏈接?

gcc默認的是動態(tài)鏈接的(建議行為),對于一個特定庫來說,究竟是動態(tài)庫還是靜態(tài)庫,取決于你提供的是動態(tài)庫還是靜態(tài)庫,動態(tài)庫和靜態(tài)庫都給gcc默認是動態(tài)鏈接。

形成一個執(zhí)行成程序,可能不僅僅依賴一個庫。
對于多個庫,gcc也是一個個進行鏈接的。

對于執(zhí)行一個進程,需要再命令行寫一大推的命令,顯得太麻煩了。
我們可以把庫安裝到指定路徑下。

ls /usr/include  //頭文件
ls /lib64        //庫文件
sudo cp mylib/include/* /usr/include //安裝頭文件
sudo cp mylib/lib/*.a /lib64         //安裝庫文件

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
我明明將頭文件和庫文件安裝到指定目錄下了,為什么還報錯?這里肯定是是把相應的文件加載到相應的位置。

還記得上面提過,使用第三方庫要指定庫名稱。

這里加上庫名稱就好了。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

刪除

sudo rm /usr/include/my_ *
sudo rm /lib65/libmymath.a

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

生成動態(tài)庫

shared: 表示生成共享庫格式
fPIC:產(chǎn)生位置無關碼(position independent code)
庫名規(guī)則:libxxx.so

位置無關碼,等到動態(tài)庫加載原理細說。

gcc -c -fPIC my_add.c
gcc -c -fPIC my_sub.c

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

gcc -shared -o libmymath.so my_add.o my_sub.o

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
這里沒有再像靜態(tài)庫那樣麻煩再打包什么的,而是直接把動態(tài)庫拷貝過去,都是一樣的效果。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

gcc -o mymath main.c -I./mylib/include -L./mylib/lib -lmymath

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
加載共享庫時出錯:libmymath.so:無法打開共享對象文件:沒有這樣的文件或目錄。為什么出現(xiàn)找不到的錯誤?

我不是已經(jīng)告訴庫文件,路徑和庫名稱了嘛。
告訴誰了?
我其實只是告訴gcc了,當把程序編譯完,和gcc還有關系嗎?
和gcc沒有關系了。
程序運行起來,OS和shell也是需要知道庫再哪里的!而自己庫根本沒有在系統(tǒng)指定路徑下,因此OS無法找到。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

這里介紹四種解決方法。

3.2.1通過環(huán)境變量找到動態(tài)庫路徑

程序在加載進程時,除了在默認路徑下找,也會在LD_LIBRAY_PATH路徑下找。

echo $LD_LIBRARY_PATH //把路徑信息打印到顯示器

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

把庫路徑添加到環(huán)境變量里。

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/wdl/linux/test_10_28/mylib/lib

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
然后運行就沒問題了。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
但是當我重新登錄shell時,發(fā)現(xiàn)又不能運行了。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
這是因為我們修改的只是子進程的環(huán)境變量,當子進程退出,在重新登錄shell,如果不對該子進程的環(huán)境變量進行修改,它默認用的是父進程的也就是shell的環(huán)境變量。

3.2.2把動態(tài)庫拷貝到默認路徑下

sudo cp mylib/include/* /usr/include //安裝頭文件
sudo cp mylib/lib/*.so /lib64         //安裝庫文件

3.2.3添加到配置文件中

cd /etc/ld.so.conf.d 

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
這些都是系統(tǒng)默認給我們配置好的文件。

sudo touch lib.conf

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

sudo vim lib.conf

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
當配置文件寫好保存退出
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
發(fā)現(xiàn)還是找不到錯誤,這是因為寫完配置文件需要更新一下。

sudo ldconfig

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
這樣就沒問題了。

如果要刪除剛才的配置文件,在刪除之后也需要sudo ldconfig更新一下。

3.2.4建立軟鏈接

最簡單的方法就是建立軟鏈接

ln -s /home/wdl/linux/test_10_28/mylib/lib/libmymath.so libmymath.so

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
在當前目錄下,給我們的庫建立一個軟鏈接,然后運行./mymath可以正確運行,說明在搜索動態(tài)庫的時候,就能夠默認在當前目錄下搜索。

如果不想在當前目錄下建立軟鏈接,就想在系統(tǒng)中可以用它??梢园堰@個軟鏈接建立到對應的系統(tǒng)路徑下。

sudo ln -s /home/wdl/linux/test_10_28/mylib/lib/libmymath.so /lib64/libmymath.so

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

3.3動靜態(tài)庫的加載原理

3.3.1靜態(tài)庫加載原理

其實靜態(tài)庫并不需要加載,在編譯可執(zhí)行程序的時候,只是把靜態(tài)庫里面的代碼拷貝一份給可執(zhí)行程序,需要一份就拷貝一份,需要多份就拷貝多份。

那把庫代碼拷貝到可執(zhí)行程序的哪里呢?
拷貝到代碼區(qū)??蓤?zhí)行程序文件本身也有邏輯地址,靜態(tài)庫在該文件的代碼區(qū)從0x00000000 到0xffffffff編址。

但是當可執(zhí)行程序加載到內(nèi)存中,這些重復的代碼就造成了內(nèi)存空間的浪費。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
靜態(tài)庫是以絕對編制的方式在該文件的代碼區(qū)進行編制的。

3.3.2動態(tài)庫加載原理

靜態(tài)鏈接是將靜態(tài)庫的代碼通過絕對編制的方式拷貝到可執(zhí)行程序的代碼區(qū)。而動態(tài)鏈接是將動態(tài)庫里指定函數(shù)的地址,寫入到我們的可執(zhí)行程序中。

這個地址是偏移地址,就是相對于libc.so(動態(tài)庫)的地址。

假設動態(tài)鏈接調(diào)用的是printf函數(shù),就將printf函數(shù)在動態(tài)庫中的偏移量寫入到可執(zhí)行程序中。

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

當執(zhí)行到printf時,經(jīng)過頁表讀取時發(fā)現(xiàn)在可執(zhí)行程序中這個這個printf代碼不存在。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
但是在編譯的時就在可執(zhí)行程序表明這是一個外部地址,需要訪問動態(tài)庫庫。因此OS先暫停執(zhí)行printf,而先將動態(tài)庫加載到內(nèi)存,然后將庫中的內(nèi)容經(jīng)過頁表映射到進程的共享區(qū)。
【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維
動態(tài)庫經(jīng)過頁表映射到共享區(qū),立馬就決定了這個庫的起始地址。

雖然在可執(zhí)行程序中printf語句只是說我們用了那些庫。但是不用擔心,在鏈接的時候,printf中已經(jīng)填寫好了printf在庫的偏移量!

因此當想調(diào)用printf的時候,庫一旦完成了加載,映射的過程之后。想跳轉(zhuǎn)執(zhí)行動態(tài)庫中的方法,直接在自己的上下文中跳轉(zhuǎn)。

庫加載進來,然后就知道了這個庫在共享區(qū)的地址(也是這個庫的起始地址),這時只要拿著printf在鏈接時的形成的printf在庫中的偏移量,再加上這個庫的起始地址,就找到這個代碼在共享區(qū)的地址,然后去調(diào)用這個函數(shù),調(diào)用結束之后,再返回代碼處向后繼續(xù)執(zhí)行。

【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫,Linux,linux,性能優(yōu)化,運維

這就是動態(tài)庫訪問,加載的過程。文章來源地址http://www.zghlxwxcb.cn/news/detail-727746.html

到了這里,關于【linux】文件系統(tǒng)+軟硬連接+動靜態(tài)庫的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領支付寶紅包贊助服務器費用

相關文章

  • Linux文件系列:磁盤,文件系統(tǒng),軟硬鏈接

    Linux文件系列:磁盤,文件系統(tǒng),軟硬鏈接

    我們之前所學的都是被進程打開了的文件,接下來我們要學習沒有被進程所打開的文件,它們是存儲在磁盤當中的 要學習這些文件,首先我們要先學習一下磁盤 1.LBA地址 我們知道磁帶在展開之后呈現(xiàn)一種帶狀結構,磁帶中的數(shù)據(jù)就是以這種線性的方式進行存儲的 那么我們可不可以

    2024年03月27日
    瀏覽(20)
  • Linux之文件系統(tǒng)與軟硬鏈接

    Linux之文件系統(tǒng)與軟硬鏈接

    目錄 一、磁盤 1、磁盤的物理結構 2、磁盤的存儲結構 3、磁盤的抽象結構 二、文件系統(tǒng)與inode 1、初識inode 2、文件系統(tǒng) 3、用inode編號找文件屬性和內(nèi)容 4、inode和文件名的關系 5、創(chuàng)建一個文件 6、查看一個文件 7、刪除一個文件 三、軟硬鏈接 1、軟連接 2、硬鏈接 磁盤可以存

    2024年02月03日
    瀏覽(22)
  • 【Linux】15. 文件系統(tǒng)與軟硬鏈接

    【Linux】15. 文件系統(tǒng)與軟硬鏈接

    在之前的學習過程當中,我們知道當文件被打開后需要加載進內(nèi)存,第一步為其創(chuàng)建struct file結構體描述其結構(操作系統(tǒng)需要管理被打開的文件:先描述再組織),在通過進程當中的文件描述符指針指向文件描述符表,根據(jù)文件描述符的分配規(guī)則給新打開的文件分配文件描述符

    2024年02月09日
    瀏覽(19)
  • 【Linux】磁盤結構 | 文件系統(tǒng) | 軟硬鏈接

    【Linux】磁盤結構 | 文件系統(tǒng) | 軟硬鏈接

    文件的狀態(tài)有被打開和沒有被打開,之前談到一個文件被進行讀寫,就要打開加載到內(nèi)存中,通過對應的系統(tǒng)調(diào)用,fd文件描述符的管理,write和read等函數(shù)的增刪查改。并且借助緩沖區(qū)對文件屬性和內(nèi)容的修改。 大部分文件是沒有被打開的(不需要訪問),都在磁盤里保存的

    2024年01月20日
    瀏覽(26)
  • 【Linux】-文件系統(tǒng)的詳解以及軟硬鏈接

    【Linux】-文件系統(tǒng)的詳解以及軟硬鏈接

    ??作者:小樹苗渴望變成參天大樹?? ??作者宣言:認真寫好每一篇博客?? ??作者gitee:gitee? ??作者專欄:C語言,數(shù)據(jù)結構初階,Linux,C++ 動態(tài)規(guī)劃算法?? 如 果 你 喜 歡 作 者 的 文 章 ,就 給 作 者 點 點 關 注 吧! 今天我們開始講解文件系統(tǒng),上一篇我們通過文件操作,

    2024年02月04日
    瀏覽(29)
  • 【Linux】文件系統(tǒng)軟硬鏈接的那些事兒

    【Linux】文件系統(tǒng)軟硬鏈接的那些事兒

    作者:?舊言~ 座右銘:松樹千年終是朽,槿花一日自為榮。 目標:理解什么是軟硬鏈接,并且能創(chuàng)建軟硬鏈接。 毒雞湯:再小的事,別人做了是情分,不做是本分。可是有些人,永遠只要求他人付出,不懂得感恩。 專欄選自:Linux初階 望小伙伴們點贊??收藏?加關注喲????

    2024年04月22日
    瀏覽(25)
  • 【Linux】什么是文件系統(tǒng)及inode?如何創(chuàng)建軟硬鏈接?軟硬鏈接有什么作用?

    【Linux】什么是文件系統(tǒng)及inode?如何創(chuàng)建軟硬鏈接?軟硬鏈接有什么作用?

    了解一下文件系統(tǒng): Linux ext2文件系統(tǒng),上圖為磁盤文件系統(tǒng)圖(內(nèi)核內(nèi)存映像肯定有所不同),磁盤是典型的塊設備,硬盤分區(qū)被 劃分為一個個的block。一個block的大小是由格式化的時候確定的,并且不可以更改。例如mke2fs的-b選項可以設 定block大小為1024、2048或4096字節(jié)。而

    2024年02月11日
    瀏覽(19)
  • 【Linux】基礎 IO(文件系統(tǒng) & inode & 軟硬鏈接)-- 詳解

    【Linux】基礎 IO(文件系統(tǒng) & inode & 軟硬鏈接)-- 詳解

    1、前言 我們一直都在說打開的文件,磁盤中包含了上百萬個文件,肯定不可能都是以打開的方式存在。其實文件包含打開的文件和普通的未打開的文件,下面重點談談未打開的文件。 我們知道打開的文件是通過操作系統(tǒng)被進程打開,一旦打開,操作系統(tǒng)就要維護多個文件,

    2024年03月21日
    瀏覽(30)
  • 【Linux】軟硬鏈接 / 動靜態(tài)庫

    【Linux】軟硬鏈接 / 動靜態(tài)庫

    硬鏈接(hard link) 可以將它理解為原始文件的別名, 和原始文件使用相同的 inode 編號和 data block.(inode 是文件在該磁盤分區(qū)內(nèi)的唯一標識, 記錄著文件的屬性等內(nèi)容; data block 是文件的內(nèi)容) 可以使用 ln 指令為文件創(chuàng)建一個硬鏈接. 當創(chuàng)建一個新的硬鏈接時, 該文件的硬鏈接數(shù)就會

    2024年04月08日
    瀏覽(17)
  • 【Linux】文件系統(tǒng)中inode與軟硬鏈接以及讀寫權限問題

    【Linux】文件系統(tǒng)中inode與軟硬鏈接以及讀寫權限問題

    我們接下來以磁盤舉例: 文件=文件內(nèi)容+文件屬性 Linux中文件內(nèi)容與屬性是分開存儲的。 文件內(nèi)容:在數(shù)據(jù)塊中存著 文件屬性:在inode中存著 Block Group:ext2文件系統(tǒng)會根據(jù)分區(qū)的大小劃分為數(shù)個Block Group。而每個Block Group都有著相同的結構組成。政府管理各區(qū)的例子 超級塊(

    2024年02月05日
    瀏覽(23)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領取紅包,優(yōu)惠每天領

二維碼1

領取紅包

二維碼2

領紅包