侵權投訴

四個方面全面解析Linux 下 C++ 編譯&鏈接

開關電源芯片 ? 2021-08-27 09:36 ? 次閱讀

【導讀】:編譯與鏈接對C++&C++程序員既熟悉又陌生,熟悉在于每份代碼都要經歷編譯與鏈接過程,陌生在于大部分人并不會刻意關注編譯與鏈接的原理。本文通過開發過程中碰到的四個典型問題來探索64位linux下C++編譯&鏈接的那些事。

以下是正文

編譯原理

將如下最簡單的C++程序(main.cpp)編譯成可執行目標程序,實際上可以分為四個步驟:預處理、編譯、匯編、鏈接,可以通過

g++ main.cpp –v看到詳細的過程,不過現在編譯器已經把預處理和編譯過程合并。

預處理:g++ -E main.cpp -o main.ii,-E表示只進行預處理。預處理主要是處理各種宏展開;添加行號和文件標識符,為編譯器產生調試信息提供便利;刪除注釋;保留編譯器用到的編譯器指令等。

編譯:g++ -S main.ii –o main.s,-S表示只編譯。編譯是在預處理文件基礎上經過一系列詞法分析、語法分析及優化后生成匯編代碼。

匯編:g++ -c main.s –o main.o。匯編是將匯編代碼轉化為機器可以執行的指令。

鏈接:g++ main.o。鏈接生成可執行程序,之所以需要鏈接是因為我們代碼不可能像main.cpp這么簡單,現代軟件動則成百上千萬行,如果寫在一個main.cpp既不利于分工合作,也無法維護,因此通常是由一堆cpp文件組成,編譯器分別編譯每個cpp,這些cpp里會引用別的模塊中的函數或全局變量,在編譯單個cpp的時候是沒法知道它們的準確地址,因此在編譯結束后,需要鏈接器將各種還沒有準確地址的符號(函數、變量等)設置為正確的值,這樣組裝在一起就可以形成一個完整的可執行程序。

問題一:頭文件遮擋

在編譯過程中最詭異的問題莫過于頭文件遮擋,如下代碼中main.cpp包含頭文件common.h,真正想用的頭文件是圖中最右邊那個包含name

c984c19a-f62b-11eb-9bcf-12bb97331649.png

成員的文件(所在目錄為。/include),但在編譯過程中中間的common.h(所在目錄為。/include1)搶先被發現,導致編譯器報錯:Test結構沒有name成員,對程序員來講,自己明明定義了name成員,居然說沒有name這個成員,如果第一次碰到這種情況可能會懷疑人生。應對這種詭異的問題,我們可以用-E參數看下編譯器預處理后的輸出,如下圖。

c9b0d500-f62b-11eb-9bcf-12bb97331649.jpg

預處理文件格式如下:# linenum filename flag,表示之后的內容是從文件名為filaname的文件中第linenum行展開的,flag的取值可以是1,2,3,4,可以是用空格分開的多值,1表示接下來要展開一個新文件;2表示一個文件展開完畢;3表示接下來內容來自一個系統頭文件;4表示接下來的內容應該看做是extern C形式引入的。

從展開后的輸出我們可以清楚地看到Test結構確實沒有定義name這個成員,并且Test這個結構是在。/include1中的common.h中定義的,到此真相大白,編譯器壓根就沒用我們定義的Test結構,而是被別的同名頭文件截胡了。我們可以通過調整-I或者在頭文件中帶上部分路徑更詳細制定頭文件位置來解決。

目標文件:

編譯鏈接最終會生成各種目標文件,Linux下目標文件格式為ELF(Executable Linkable Format),詳細定義見/usr/include/elf.h頭文件,常見的目標文件有:可重定位目標文件,也即.o結尾的目標文件,當然靜態庫也歸為此類;可執行文件,比如默認編譯出的a.out文件;共享目標文件.so;核心轉儲文件,也就是core dump后產出的文件。Linux文件格式可以通過file命令查看。

一個典型的ELF文件格式如下圖所示,文件有兩種視角:編譯視角,以section頭部表為核心組織程序;運行視角,程序頭部表以segment為核心組織程序。這么做主要是為了節約存儲,很多細碎的section在運行時由于對齊要求會導致很大的內存浪費,運行時通常會將權限類似的section組織成segment一起加載。

通過命令objdump和readelf可以查看ELF文件的內容。

對可重定位目標文件常見的section有:

ca2e1600-f62b-11eb-9bcf-12bb97331649.png

符號解析:

鏈接器會為對外部符號的引用修改為正確的被引用符號的地址,當無法為引用的外部符號找到對應的定義時,鏈接器會報undefined reference to XXXX的錯誤。另外一種情況是,找到了多個符號的定義,這種情況鏈接器有一套規則。在描述規則前需要了解強符號和弱符號的概念,簡單講函數和已初始化的全局變量是強符號,未初始化的全局變量是弱符號。

針對符號的多重定義鏈接器處理規則如下(作者在gcc 7.3.0上貌似規則2,3都按1處理):

1. 不允許多個強符號定義,鏈接器會報告重復定義貌似的錯誤

2. 如果一個強符號和多個弱符號同名,則選擇強符號

3. 如果符號在所有目標文件中都為弱符號,那么選擇占用空間最大的一個

有了這些基礎,我們先來看一下靜態鏈接過程:

1. 鏈接器從左到右按照命令行出現順序掃描目標文件和靜態庫

2. 鏈接器維護一個目標文件的集合E,一個未解析符號集合U,以及E中已定義的符號集合D,初始狀態E、U、D都為空

3. 對命令行上每個文件f,鏈接器會判斷f是否是一個目標文件還是靜態庫,如果是目標文件,則f加入到E,f中未定義的符號加入到U中,已定義符號加入到D中,繼續下一文件

4. 如果是靜態庫,鏈接器嘗試到靜態庫目標文件中匹配U中未定義的符號,如果m中匹配U中的一個符號,那么m就和上步中文件f一樣處理,對每個成員文件都依次處理,直到U、D無變化,不包含在E中的成員文件簡單丟棄

5. 所有輸入文件處理完后,如果U中還有符號,則出錯,否則鏈接正常,輸出可執行文件

問題二:靜態庫順序

如下圖所示,main.cpp依賴liba.a,liba.a又依賴libb.a,根據靜態鏈接算法,如果用g++ main.cpp liba.a libb.a的順序能正常鏈接,因為解析liba.a時未定義符號FunB會加入到上述算法的U中,然后在libb.a中找到定義。

如果用g++ main.cpp libb.a liba.a的順序編譯,則無法找到FunB的定義,因為根據靜態鏈接算法,在解析libb.a的時候U為空,所以不需要做任何解析,簡單拋棄libb.a,但在解析liba.a的時候又發現FunB沒有定義,導致U最終不為空,鏈接錯誤。

因此在做靜態鏈接時,需要特別注意庫的順序安排,引用別的庫的靜態庫需要放在前面,碰到鏈接很多庫的時候,可能需要做一些庫的調整,從而使依賴關系更清晰。

ca48b7c6-f62b-11eb-9bcf-12bb97331649.png

動態鏈接:

之前大部分內容都是靜態鏈接相關,但靜態鏈接有很多不足:不利于更新,只要有一個庫有變動,都需要重新編譯;不利于共享,每個可執行程序都單獨保留一份,對內存和磁盤是極大的浪費。

要生成動態鏈接庫需要用到參數“-shared -fPIC”表示要生成位置無關PIC(Position Independent Code)的共享目標文件。對靜態鏈接,在生成可執行目標文件時整個鏈接過程就完成了,但要想實現動態鏈接的效果,就需要把程序按照模塊拆分成相對獨立的部分。

在程序運行時將他們鏈接成一個完整的程序,同時為了實現代碼在不同程序間共享要保證代碼是和位置無關的(因為共享目標文件在每個程序中被加載的虛擬地址都不一樣,要保證它不管被加載在哪都能工作),而為了實現位置無關又依賴一個前提:數據段和代碼段的距離總是保持不變。

由于不管在內存中如何加載一個目標模塊,數據段和代碼段間的距離是不變的,編譯器在數據段前面引入了一個全局偏移表GOT(Global Offset Table),被引用的全局變量或者函數在GOT中都有一條記錄,同時編譯器為GOT中每個條目生成一個重定位記錄,因為數據段是可以修改的,動態鏈接器在加載時會重定位GOT中的每個條目,這樣就實現了PIC。

大體原理基本就這樣,但具體實現時,對函數的處理和全局變量有所不同。由于大型程序函數成千上萬,而程序很可能只會用到其中的一小部分,因此沒必要加載的時候把所有的函數都做重定位,只有在用到的時候才對地址做修訂。

為此編譯器引入了過程鏈接表PLT(Procedure Linkage Table)來實現延時綁定。PLT在代碼段中,它指向了GOT中函數對應的地址,第一次調用時候,GOT存放的不是函數的實際地址,而是PLT跳轉到GOT代碼的后一條指令地址。

這樣第一次通過PLT跳轉到GOT,然后通過GOT又調回到PLT的下一條指令,相當于什么也沒做,緊接著PLT后面的代碼會將動態鏈接需要的參數入棧,然后調用動態鏈接器修正GOT中的地址,從這以后,PLT中代碼跳轉到GOT的地址就是函數真正的地址,從而實現了所謂的延時綁定。

對共享目標文件而言,有幾個需要關注的section:

ca5aa10c-f62b-11eb-9bcf-12bb97331649.png

有了以上基礎后,我們看一下動態鏈接的過程:

1. 裝載過程中程序執行會跳轉到動態鏈接器

2. 動態鏈接器自舉通過GOT、.dynamic信息完成自身的重定位工作

3. 裝載共享目標文件:將可執行文件和鏈接器本身符號合并入全局符號表,依次廣度優先遍歷共享目標文件,它們的符號表會不斷合并到全局符號表中,如果多個共享對象有相同的符號,則優先載入的共享目標文件會屏蔽掉后面的符號

4. 重定位和初始化

問題三:全局符號介入

動態鏈接過程中最關鍵的第3步可以看到,當多個共享目標文件中包含一個相同的符號,那么會導致先被加載的符號占住全局符號表,后續共享目標文件中相同符號被忽略。當我們代碼中沒有很好的處理命名的話,會導致非常奇怪的錯誤,幸運的話立刻core dump,不幸的話直到程序運行很久以后才莫名其妙的core dump,甚至永遠不會core dump但是結果不正確。

如下圖所示,main.cpp中會用到兩個動態庫libadd.so,libadd1.so的符號,我們把重點

ca741d12-f62b-11eb-9bcf-12bb97331649.png

放在Add函數的處理上,當我們以g++ main.cpp libadd.so libadd1.so編譯時,程序輸出“Add in add lib”說明Add是用的libadd.so中的符號(add.cpp),當我們以g++ main.cpp libadd1.so libadd.so編譯時。

程序輸出“Add in add1 lib”說明Add是用的libadd1.so中的符號,這時候問題就大了,調用方main.cpp中認為Add只有兩個參數,而add1.cpp中認為Add有三個參數,程序中如果有這樣的代碼,可以預見很可能造成巨大的混亂。

具體符號解析我們可以通過LD_DEBUG=all 。/a.out來觀察Add的解析過程,如下圖所示:左邊是對應libadd.so在編譯時放在前面的情況,Add綁定在libadd.so中,右邊對應libadd1.so放前面的情況,Add綁定在libadd1.so中。

caa41b20-f62b-11eb-9bcf-12bb97331649.png

運行時加載動態庫:

有了動態鏈接和共享目標文件的加持,Linux提供了一種更加靈活的模塊加載方式:通過提供dlopen,dlsym,dlclose,dlerror幾個API,可以實現在運行的時候動態加載模塊,從而實現插件的功能。

如下代碼演示了動態加載Add函數的過程,add.cpp按照正常編譯“g++ -fPIC –shared –o libadd.so add.cpp”成libadd.so,main.cpp通過“g++ main.cpp -ldl”編譯為a.out。main.cpp中首先通過dlopen接口取得一個句柄void *handle。

然后通過dlsym從句柄中查找符號Add,找到后將其轉化為Add函數,然后就可以按照正常的函數使用,最后dlclose關閉句柄,期間有任何錯誤可以通過dlerror來獲取。

caef8b32-f62b-11eb-9bcf-12bb97331649.jpg

問題四:靜態全局變量與動態庫導致double free

在全面了解了動態鏈接相關知識后,我們來看一個靜態全局變量和動態庫糾結在一起引發的問題,代碼如下,foo.cpp中有一個靜態全局對象foo_,foo.cpp會編譯成一個libfoo.a,bar.cpp依賴libfoo.a庫,它本身會編譯成libbar.so,main.cpp既依賴于libfoo.a又依賴libbar.so。

caf98eac-f62b-11eb-9bcf-12bb97331649.jpg

編譯的makefile如下:

cb1d0724-f62b-11eb-9bcf-12bb97331649.png

運行a.out會導致double free的錯誤。這是由于在一個位置上調用了兩次析構函數造成的。之所以會這樣是因為鏈接的時候先鏈接的靜態庫,將foo_的符號解析為靜態庫中的全局變量,當動態鏈接libbar.so時,由于全局已經有符號foo_,因此根據全局符號介入,動態庫中對foo_的引用會指向靜態庫中版本,導致最后在同一個對象上析構了兩次。

cb2b9a28-f62b-11eb-9bcf-12bb97331649.png

解決辦法如下:

1. 不使用全局對象

2. 編譯時候調換庫的順序,動態庫放在前面,這樣全局只會有一個foo_對象

3. 全部使用動態庫

4. 通過編譯器參數來控制符號的可見性。

總結:

通過四個編譯鏈接中碰到的問題,基本把編譯鏈接的這些事覆蓋了一遍,有了這些基礎,在日常工作中應對一般的編譯鏈接問題應該可以做到游刃有余。由于篇幅有限,文章省略了大量的細節,主要集中在大的框架原理性梳理,如果想進一步深挖相關的細節,可參與相關參考文獻,以及閱讀elf.h相關的頭文件。

轉自:https://my.oschina.net/u/4526289/blog/4651990

編輯:jq

原文標題:從四個問題透析 Linux 下 C++ 編譯&鏈接

文章出處:【微信號:gh_3980db2283cd,微信公眾號:開關電源芯片】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏
分享:

評論

相關推薦

微軟官方開發的VS Code擴展介紹

【導語】:CodeTour(代碼之旅)是微軟官方開發的 VS Code 擴展,允許記錄和回放代碼的演....
的頭像 數據分析與開發 發表于 10-22 17:13 ? 187次 閱讀

2021華為開發者大會:鴻蒙智聯設備開發效率倍增

2021華為開發者大會:分布式應用服務開發環境,以用戶為中心的自然智慧交互,突破跨端開發調試困難,豐....
的頭像 lhl545545 發表于 10-22 15:57 ? 246次 閱讀
2021華為開發者大會:鴻蒙智聯設備開發效率倍增

2021華為開發者大會:方舟編譯器3.0支持多設備協同

2021華為開發者大會:高性能的方舟開發框架內存占用可以節省59%,使能開發者從單設備跨入多設備發展....
的頭像 lhl545545 發表于 10-22 15:23 ? 190次 閱讀
2021華為開發者大會:方舟編譯器3.0支持多設備協同

華為開發者大會2021:軟件部總裁龔體 鴻蒙系統 一次開發 多端部署 萬物互連

華為開發者大會2021:鴻蒙系統 一次開發 多端部署 萬物互連 在華為開發者大會2021上,華為消費....
的頭像 inr999 發表于 10-22 15:09 ? 317次 閱讀
華為開發者大會2021:軟件部總裁龔體 鴻蒙系統 一次開發 多端部署 萬物互連

怎樣用printf 函數和getchar 函數去簡化STM32串口數據的傳輸呢

printf 函數和getchar 函數有何功能? 怎樣用printf 函數和getchar 函數去簡化STM32串口數據的傳輸呢? ...
發表于 10-22 07:49 ? 0次 閱讀

怎樣去設計一種基于單片機的智能窗簾呢

怎樣去設計一種基于單片機的智能窗簾呢?怎樣去編寫其主函數代碼呢?...
發表于 10-22 07:29 ? 0次 閱讀

STM32F103C8T6的串口配置步驟有哪些

STM32F103C8T6有哪幾個串口? STM32F103C8T6的串口配置步驟有哪些?怎樣去編寫代碼呢? ...
發表于 10-22 06:35 ? 0次 閱讀

華為開發者大會2021年的時間

2021年10月22日~24日,華為將在中國松山湖舉行2021華為開發者大會,聚焦鴻蒙系統、智能家居....
的頭像 汽車玩家 發表于 10-21 16:13 ? 729次 閱讀

C語言堆棧程序內存的分配

? ? 程序內存的分配 ? ????一個由C/C++編譯的程序占用的內存分為以下幾個部分: 棧區(s....
的頭像 嵌入式ARM 發表于 10-21 14:51 ? 77次 閱讀

ML規模復雜的相關基礎架構

? Waze 是世界上最大的基于社區的交通和導航應用。該應用借助實時數據來幫助用戶避開路上的障礙,享....
的頭像 TensorFlow 發表于 10-21 14:07 ? 122次 閱讀

【嵌入式實驗】《嵌入式開發工具使用》

嵌入式開發工具使用一.實驗目的二.實驗內容三.預備知識四.實驗設備及工具(包括軟件調試工具)五.實驗....
發表于 10-21 13:06 ? 7次 閱讀
【嵌入式實驗】《嵌入式開發工具使用》

嵌入式c語言 c語言_C和嵌入式C有什么區別?

嵌入式c語言 c語言C programming language was designed by t....
發表于 10-21 10:21 ? 6次 閱讀
嵌入式c語言 c語言_C和嵌入式C有什么區別?

從存儲器哪一個位置開始讀取代碼呢

代碼是從哪里開始運行的? 從存儲器哪一個位置開始讀取代碼呢?...
發表于 10-21 09:11 ? 0次 閱讀

串口通信的相關代碼學習

怎樣去編寫一種簡單的串口通信代碼呢? 什么是SBUF? ...
發表于 10-21 09:10 ? 0次 閱讀

如何對STM32H747 / STM32H745進行測試

STM32H747/757系列產品有哪些性能? 如何對STM32H747 / STM32H745進行測試? ...
發表于 10-21 08:24 ? 0次 閱讀

怎樣用最新版的MDK530去編譯原來的代碼呢

怎樣用最新版的MDK530去編譯原來的代碼呢? MDK530編譯為什么會出現ARM版本不符的問題? ...
發表于 10-21 07:26 ? 0次 閱讀

探究IntelliJ IDEA 中JAVA代碼的任務標記

【任務標記是以注釋的方式定義】 一、作用:1、可以大大的提高開發效率。代碼量非常大的項目,在某一行中....
的頭像 Android編程精選 發表于 10-20 17:10 ? 224次 閱讀
探究IntelliJ IDEA 中JAVA代碼的任務標記

詳細介紹go語言中的閉包的實現

什么是閉包? 什么場景下會用閉包 ? 本文對 go 語言中的閉包做了詳細介紹。 閉包是由函數及其相關....
的頭像 馬哥Linux運維 發表于 10-20 16:18 ? 223次 閱讀

詳細剖析內核究竟是如何求解結構體成員變量的地址

今天我們來詳細剖析下 內核到底是如何求解結構體成員變量的地址的 。 1. 結構體在內存中是如何存儲的....
的頭像 Linux愛好者 發表于 10-20 15:46 ? 203次 閱讀

簡述Python加速運行小竅門

Python 是一種腳本語言,相比 C/C++ 這樣的編譯語言,在效率和性能方面存在一些不足。但是,....
的頭像 Linux愛好者 發表于 10-20 15:28 ? 574次 閱讀

簡述ElasticSearch的實現

1.近實時搜索 1.1 實時與近實時 實時搜索(Real-time Search)很好理解,對于一個....
的頭像 馬哥Linux運維 發表于 10-20 14:45 ? 233次 閱讀

Python協程與JavaScript協程的對比及經驗技巧

前言以前沒怎么接觸前端,對 JavaScript 的異步操作不了解,現在有了點了解。一查發現 Pyt....
的頭像 馬哥Linux運維 發表于 10-20 14:30 ? 163次 閱讀

設置I幀的QP的示例代碼

? 介紹 在有些應用中,發現I幀不夠大。MPSoC VCU CtrlSW可以設置每一幀的QP大小。因....
的頭像 FPGA開發圈 發表于 10-20 11:35 ? 235次 閱讀

IAP編程page0返回失敗的問題總結

最近在支持客戶的時候遇到這樣一個問題:客戶在做自己的二級boot loader,并且在使用LPC54....
的頭像 恩智浦MCU加油站 發表于 10-20 10:59 ? 194次 閱讀
IAP編程page0返回失敗的問題總結

pyBGAPI藍牙代碼庫的軟件結構

新的Python代碼庫-pyBGAPI可幫助開發人員通過Silicon Labs(亦稱“芯科科技”)....
的頭像 SiliconLabs 發表于 10-20 09:57 ? 150次 閱讀

無接口驅動程序基于ATEasy代碼功能

作為一款新型的自動化測試軟件,ATEasy 驅動程序為 ATEasy 應用程序提供了一種與設備或儀器....
的頭像 廣州虹科電子科技有限公司 發表于 10-20 09:29 ? 122次 閱讀

怎樣去操作基于STM32F407 HAL庫的Flash編程呢

怎樣去操作基于STM32F407 HAL庫的Flash編程呢? flash的寫入操作是怎樣的? ...
發表于 10-20 06:05 ? 0次 閱讀

如何去實現一種基于51最小系統的跑馬燈設計

如何去實現一種基于51最小系統的跑馬燈設計?...
發表于 10-20 06:01 ? 0次 閱讀

簡述圖像梯度的基本原理

當用均值濾波器降低圖像噪聲的時候,會帶來圖像模糊的副作用。我們當然希望看到的是清晰圖像。那么,清晰圖....
的頭像 新機器視覺 發表于 10-19 16:22 ? 151次 閱讀
簡述圖像梯度的基本原理

深入探討 Hilt的工作原理

所涉主題 ?? ? 多種 Hilt 注解協同工作并生成代碼的方式。 當 Hilt 配合 Gradle....
的頭像 谷歌開發者 發表于 10-19 15:11 ? 181次 閱讀
深入探討 Hilt的工作原理

一文了解Cortex-M中斷向量表對齊原則

來源 | 痞子衡嵌入式 一、Cortex-M中斷向量表對齊原則 ? 中斷向量表就是一個集中保存系統全....
的頭像 strongerHuang 發表于 10-19 11:06 ? 220次 閱讀
一文了解Cortex-M中斷向量表對齊原則

中斷優先級配置的函數有哪幾種

中斷優先級配置的函數有哪幾種? 怎樣去比較搶占優先級與響應優先級呢? ...
發表于 10-19 08:02 ? 0次 閱讀

PIC16LF1933的應用范例合集

PIC16LF1933的應用范例合集
發表于 10-18 18:07 ? 28次 閱讀

關于Python18個你不知道的高效編程技巧

初識Python語言,覺得python滿足了我上學時候對編程語言的所有要求。python語言的高效編....
的頭像 馬哥Linux運維 發表于 10-15 11:23 ? 264次 閱讀

PCB的設計、打板和焊接

最近MicroPython在嵌入式系統領域受到大家的喜愛,攻城獅們都紛紛研究起來,就連我們Funpa....
的頭像 電子森林 發表于 10-15 10:04 ? 225次 閱讀

能快速找到代碼運行最慢部分的編程神器

天下武功,唯快不破。 編程也不例外,你的代碼跑的快,你能快速找出代碼慢的原因,你的碼功就高。 今天分....
的頭像 Linux愛好者 發表于 10-13 16:40 ? 144次 閱讀

動態內存分配的注意事項及本質是什么

C語言中比較重要的就是指針,它可以用來鏈表操作,談到鏈表,很多時候為此分配內存采用動態分配而不是靜態....
的頭像 C語言編程學習基地 發表于 10-13 15:37 ? 274次 閱讀
動態內存分配的注意事項及本質是什么

ACL2021的跨視覺語言模態論文之跨視覺語言模態任務與方法

來自:復旦DISC 引言 本次分享我們將介紹三篇來自ACL2021的跨視覺語言模態的論文。這三篇文章....
的頭像 深度學習自然語言處理 發表于 10-13 10:48 ? 249次 閱讀
ACL2021的跨視覺語言模態論文之跨視覺語言模態任務與方法

一文詳解虛函數及其相關知識點

本期是C++基礎語法分享的第七節,今天給大家來分享一下: (1)虛析構函數; (2)純虛函數; (3....
的頭像 C語言編程學習基地 發表于 10-13 10:14 ? 234次 閱讀

用Python實現3D地圖教程

前言 本文的文字及圖片來源于網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題....
的頭像 馬哥Linux運維 發表于 10-13 10:09 ? 201次 閱讀
用Python實現3D地圖教程

關于Python對交通路口的紅綠燈進行顏色檢測

轉自?|?? Python聯盟 1.視頻讀取 首先把視頻讀取進來,因為我測試的視頻是4k的所以我用r....
的頭像 新機器視覺 發表于 10-13 09:32 ? 268次 閱讀
關于Python對交通路口的紅綠燈進行顏色檢測

spring中聲明式事務實現原理猜想

? @Transactional注解簡介 @Transactional 是spring中聲明式事務管....
的頭像 Android編程精選 發表于 10-13 09:20 ? 217次 閱讀

xv6的文件系統是如何實現的

文件系統 本文繼續來看 的文件系統部分, 將文件系統的設計分為 7 層: ,磁盤、緩存區、日志三個部....
的頭像 Linux閱碼場 發表于 10-12 18:00 ? 162次 閱讀
 xv6的文件系統是如何實現的

Linux中匿名頁的訪問分析

Linux 中 有后備文件支持的頁稱為文件頁,如屬于進程的代碼段、數據段的頁,內存回收的時候這些頁面....
的頭像 Linux閱碼場 發表于 10-12 17:52 ? 184次 閱讀

處理器中異常和中斷解決

異常是能夠引起程序流偏離正常流程的事件,當異常發生時,正在執行的程序就會被掛起,處理器轉而執行一塊與....
的頭像 單片機匠人 發表于 10-12 17:14 ? 303次 閱讀

RUST的真實驅動案例

我們無法確定RUST在內核的最終趨勢,有多少人愿意遷移,但是至少Linus愿意試水。 Wedson ....
的頭像 Linux閱碼場 發表于 10-12 15:59 ? 120次 閱讀
RUST的真實驅動案例

那些有著巨大影響力的代碼盤點

2009 年,Facebook 推出了一份改變世界的代碼——點「贊」按鈕。「贊」是包括 Leah P....
的頭像 strongerHuang 發表于 10-12 15:46 ? 208次 閱讀
那些有著巨大影響力的代碼盤點

那些書本上都沒有提到的C語言volatile用法

許多程序員都無法正確理解C語言關鍵字volatile,這并不奇怪。因為大多數C語言書籍通常都是一兩句....
的頭像 STM32嵌入式開發 發表于 10-12 14:47 ? 1104次 閱讀
那些書本上都沒有提到的C語言volatile用法

什么是MicroPython 它能做什么有什么局限

隨著Python成為主流的編程語言,MicroPython在嵌入式系統領域也越來越熱門起來,尤其是大....
的頭像 電子森林 發表于 10-12 11:44 ? 272次 閱讀

PO VO DTO轉換神器的思路

當然有的人喜歡寫get set,或者用BeanUtils 進行復制,代碼只是工具,本文只是提供一種思....
的頭像 Linux愛好者 發表于 10-12 11:13 ? 232次 閱讀

如何在Colab中使用SQL

如今,編碼測試在數據科學面試過程中幾乎是標準的。 作為一名數據科學招聘經理,我發現一個20-30分鐘....
的頭像 智能感知與物聯網技術研究所 發表于 10-12 09:39 ? 205次 閱讀
如何在Colab中使用SQL

命令行工具Kubectl的別樣用法

? kubectl 是 K8s 官方附帶的命令行工具,可以方便的操作 K8s 集群。這篇文章主要介紹....
的頭像 馬哥Linux運維 發表于 10-12 09:31 ? 164次 閱讀
小仙女视频下载安装-小仙女视频app破解版-小仙女视频平台二维码