何時需要pic
華清遠見嵌入式學院講師。
「pci」其實是我們在編譯動態庫的命令列引數,我們用這個引數標記,告訴gcc產生的**不要包含對函式和變數具體記憶體位置的引用,這是因為現在還無法知道使用該訊息**的應用程式會將它連線到哪一段記憶體位址空間。這樣編譯出的*.o可以被用於建立共享鏈結庫。建立共享鏈結庫只需要用gcc的「-shared」標記即可。
現實生活中不是每個程式**都是從零開始,常常會復用別人寫好的,成熟的**,而這些**就被封裝成庫的形式,我們把編譯好的目標**儲存到「庫」裡面,要用的時候鏈結程式幫我們從庫裡面找出來。
linux下的庫有兩種:靜態庫和共享庫(動態庫)。二者的不同點在於**被載入的時刻不同。靜態庫的**在編譯過程中已經被載入可執行程式,因此體積較大。共享庫的**是在可執行程式執行時才載入記憶體的,在編譯過程中僅簡單的引用,因此**體積較小。
在早期庫的組織形式相對簡單,裡面的目標**只能夠進行靜態鏈結,所以我們稱為「靜態庫」,靜態庫的結構比較簡單,其實就是把原來的目標**放在一起,鏈結程式根據每乙份目標**的符號表查詢相應的符號(函式和變數的名字),找到的話就把該函式裡面需要定位的進行定位,然後將整塊函式**放進可執行檔案裡,若是找不到需要的函式就報錯退出。這個時候的靜態庫除了磁碟空間較大而且如果有多個(呼叫相同庫函式的)程序在記憶體中同時執行,記憶體中就存有多份相同的庫函式**,因此占用記憶體空間較多。
動態鏈結庫就是為了解決這些問題而誕生的技術,顧名思義,動態鏈結的意思就是在程式裝載記憶體的時候才真正的把庫函式**鏈結進行確定它們的位址,並且就算有幾個程式同時執行,記憶體也只存在乙份函式**。
動態庫的**要實現這樣的功能,必須滿足這樣一種條件:能夠被載入到不同程序的不同位址,所以**要經過特別的編譯處理,我們把這種經過特別處理的**叫做「位置無關**(position independed code .pic)」。
什麼叫位置無關**?也就是說記憶體中的動態**只有乙份副本,但動態庫的資料仍然可能有多份副本,因為每乙個鏈結到動態的程序都可能會修改庫的資料,每當出現這種情況的時候,作業系統就複製出乙份資料副本,然後修改程序的位址空間對映,使它指向新的資料副本,於是程序最後修改的只是屬於自己的那份資料。
其實動態庫有很多好處:
1. 可以實現程序之間的資源共享。
2. 將一些程式公升級變得簡單。使用者只需要公升級動態鏈結庫,而無需重新編譯鏈結其他原有的**就可以完成整個程式的公升級。windows 就是乙個很好的例子。
3. 甚至可以真正坐到鏈結載入完全由程式設計師在程式**中控制。
如何做到實現程序之間的資源共享?就與我們這裡所講的「**無關」相關。
再來解釋下位置無關**是什麼意思。就是說,某個程式的在執行中要呼叫某個動態鏈結庫函式的時候,作業系統首先會檢視所有正在執行的程式,看在記憶體裡是否已有此庫函式的拷貝了。如果有,則讓其共享那乙個拷貝;只有沒有才鏈結載入。這樣的模式雖然會帶來一些「動態鏈結」額外的開銷,卻大大的節省了系統的記憶體資源。c的標準庫就是動態鏈結庫,也就是說系統中所有執行的程式共享著同乙個c標準庫的**段。
由於動態鏈結庫函式的共享特性,它們不會被拷貝到可執行檔案中。在編譯的時候,編譯器只會做一些函式名之類的檢查。在程式執行的時候,被呼叫的動態鏈結庫函式被安置在記憶體的某個地方,所有呼叫它的程式將指向這個**段。因此,這些**必須實用相對位址,而不是絕對位址。在編譯的時候,我們需要告訴編譯器,這些物件檔案是用來做動態鏈結庫的,所以要用位址無關**(position independent code (pic))。
何時需要PIC
華清遠見嵌入式學院 講師。pci 其實是我們在編譯動態庫的命令列引數,我們用這個引數標記,告訴gcc產生的 不要包含對函式和變數具體記憶體位置的引用,這是因為現在還無法知道使用該訊息 的應用程式會將它連線到哪一段記憶體位址空間。這樣編譯出的 o可以被用於建立共享鏈結庫。建立共享鏈結庫只需要用gcc的...
索引何時需要 何時不需要 何時失效
總結自 前提 每次查詢都只能使用乙個索引 原因 比起全表掃瞄,分析兩個索引b 表更耗時 何時需要索引?1 所查詢欄位是主鍵 主鍵可以認為是索引 2 和其他表做連線查詢的字段 3 在where裡使用 is null和between等字段 4 不以萬用字元開始的like,如 aa 5 聚集函式max s...
多執行緒程式何時需要加鎖
簡單的說三條 多人讀,不需要 一讀一寫要加 多人寫要加 常見錯誤 1讀1寫沒事,讀寫的記憶體約多,越容易出事,因為不是原子操作 對int int64 char型是原子操作,可不加鎖,其實沒人保證這一點的,要不c 1x還出個原子模板類幹什麼 常用例項 vector的操作是安全的,如乙個執行緒裡 buf...