cgo 和 Go 語言是兩碼事

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

cgo不是Go

    借用 JWZ 的一句話

有些人,當他們面臨一個問題時,認為“我知道,我會使用 cgo ”。那麼現在,他們有了兩個問題。

最近有人在 Gopher 的 Slack Channel 上使用 cgo,對此我感到十分擔心,尤其是竟然有個組織內部打算用一個項目來展示 Go,那真是一個壞主意。對此,我曾說過很多次了,因此也許你們討厭了我的遊說,所以我想到了把它寫下來並且去做。

    cgo 是一個令人驚異的技術,它允許 Go 程式與 C 的類庫互動操作。那是一個極其有用的特徵,今天它達到了一個 Go 所無法企及的地位。cgo 是讓 Go 程式在 Android 和 iOS 上啟動並執行關鍵。

    然而,這隻是我的個人意見,我不為任何人說話,我認為 cgo 在 Go 項目中被過度使用了。我相信當面臨需要重載一大段用 Go 編寫的 C 代碼時,程式員會更願意選擇用 cgo 去打包庫而非 Go,因為他們認為那樣更容易解決問題。我認為那是虛假經濟。

    顯而易見的,cgo 也存在一些不可避免的問題,最明顯的一個問題是作為一個二進位 blog,你不得不與顯卡驅動或者視窗系統進行互動 。但是使用 cgo 所存在的問題,經過權衡後,大部分人認為還是比較少的。

    當你在 Go 項目上建立一個 cgo 庫的時候,你可能沒有意識到你的這種權衡其實是不完整的。

終日乾乾
翻譯於 4個月前

2人頂

頂 翻譯的不錯哦!

構建時間變長

當你在包中引用 import "C",go build 就會做很多額外的工作來構建你的代碼,構建就不會僅僅是向 go tool compile 傳遞一堆 .go 檔案了,取而代之的是:

  • cgo 工具就會被調用,在 C 轉換 Go、Go 轉換C的之間產生各種檔案。

  • 你系統的 C 編譯器會被調用來處理你包中所有的C檔案。

  • 所有獨立的編譯單元會被組合到一個 .o 檔案。

  •  產生的 .o 檔案會在系統的連接器中對它的引用進行一次檢查修複。

當你針對這個包編程的時候,所有上面的工作在你編譯或者測試的過程中都會進行。Go 工具在可能的情況下,會並行的處理這些工作,但是這個包的編譯時間會隨著所有 C 代碼的構建而增加。

你可以將這部分 C 代碼重構出這個包來解決,但是如果你不用 cgo,自然也就不會遇到這個問題。

對了,你還必須調試 C 代碼在不同平台的相容性問題。

drkaka
翻譯於 4個月前

0人頂

頂 翻譯的不錯哦!

複雜的構造

Go的目標之一是生產一種語言,它的構造過程就是它自我描述的過程;你程式的資源套件含了足夠的資訊來使用一個工具去建立這個項目。這不是說用 Makefile 來自動化構建工程是不好的,但是在cgo被引進項目之前,你建立並且測試不需要任何東西,除了go工具。後來cgo被引入,設定所有的環境變數、跟蹤那些可能被安裝在奇怪地方的共用對象和標頭檔,現在這些你都需要做。

記住,Go支援那些不裝載開箱即用的平台,所以你不得不花一些時間去提出一個Windows使用者的解決方案。

還有,現在你的使用者還要安裝C編譯器,而不是只安裝Go編譯器。他們同時還需要安裝你項目所依賴的C庫,所以你同時還要承擔這些支援的成本。


終日乾乾
翻譯於 4個月前

1人頂

頂 翻譯的不錯哦!

交叉編譯不支援

Go對於交叉編譯的支援是最好的。根據Go1.5交叉編譯,你可以從任何支援的平台到其他任何平台,通過Go專案網站上的官方許可安裝程式。

在預設情況下cgo是不允許交叉編譯的。 通常這不構成問題,如果你的項目是純Go的。 當你混合了C庫的依賴, 你或者不得不放棄交叉編譯你的產品,或者不得不花時間在尋找並且維護C的交叉編譯工具鏈來達成你的目標。

或許你所做的產品僅通過TCP與用戶端通訊,並且你計劃讓它在SaaS(軟體服務化 Software as a Service)的模型上運行,那麼你根本不關心交叉編譯就是合理的。然而,如果你在做一個其他人會用的產品,可能會整合到他們的產品中去,或許那是一個監控解決方案,或許那是一個你SaaS服務的用戶端,那麼你就把他們很容易交叉編譯的特性給鎖死了。

Go所支援的平台在持續地增長。Go 1.5增加了64位ARM和PowerPC的支援。Go 1.6增加了64位MIPS的支援, IBM的s390體繫結構則在Go 1.7. RISC-V中提供。如果你的產品依賴C庫,不僅你要面臨以上描述的所有交叉編譯問題,你還要確保你所依賴的C代碼在Go所支援的新平台上能可靠運行——你必須要做這些運用C/Go混合提供的有限的調試。這又引出了下面的問題。

終日乾乾
翻譯於 4個月前

1人頂

頂 翻譯的不錯哦!

你失去了通向你所有工具的入口

Go有一些偉大的工具;有競態分析、效能分析、覆蓋率、模糊測試和其他原始碼分析工具。這些中沒有任何一個能夠跨越cgo血液或是cgo大腦的屏障。

相反地,像Valgrind這樣的優秀工具不理解Go的呼叫慣例和堆棧布局。在這一點上,Ian Lance Taylor的在Go 1.6中將C的記憶體清理和null 指標調試相結合的工作對於cgo的使用者來說將會非常有益。

梳理Go的代碼和C的代碼結果到了兩個世界的交匯處,不是結盟;C的記憶體安全,Go程式的可調試性。

效能永遠是一個問題

C代碼和Go代碼生存在兩個不同的宇宙中,cgo橫貫了他們兩個之間的分界線。這個過渡並不是自由的,它取決於它在你代碼中的位置,花費可能是無足輕重的,也可能是巨額的。

終日乾乾
翻譯於 4個月前

1人頂

頂 翻譯的不錯哦!

其它翻譯版本(1)
正在載入...

C 並不瞭解 Go 的調用協定或堆棧,所以 Go 語言調用到 C 代碼時必須首先記錄 Go 函數入口堆棧的所有細節,然後切換到 C 的堆棧,運行 C 代碼,這部分 C 代碼並不知道它如何被調用,更不知道外部的 Go 語言運行時環境。

公平地說,Go 也不知道任何關於 C 的情況。這就是為什麼隨著編譯器和垃圾收集器在定位無用棧幀和堆方面的發展,Go 和 C 兩者之間傳遞資料的規則變得越來越複雜。

如果在 C 的運行過程中出現一個錯誤,Go 至少得能做到列印錯誤堆棧資訊,然後退出程式,而不是把核心檔案都暴露出來。

管理這種雙方互相調用的堆棧,再加上在訊號、線程和回調,真的很是不容易的。Ian Lance Taylor 在1.6版本的 Go 語言中做了大量的工作來改進與 C 語言訊號處理方面的互通性。

這裡要說的是 C 與 Go 語言之間的的互相調用是比較繁瑣的,而且永遠是會有效能開銷的。

雪落無痕xdj
翻譯於 4個月前

0人頂

頂 翻譯的不錯哦!

其它翻譯版本(1)
正在載入...

C 是主導,而不是你的代碼

你用那種語言捆綁或封裝C代碼都沒關係;Python、有JNI的Java、一些使用了libFFI的語言,或者是有cgo的Go;這是C的世界,你只是在其上生存。

Go代碼和C代碼必須在資源共用方式上取得一致,如地址空間、訊號處理和線程調度——而我所說的一致,是Go要圍繞著C的假設。 C代碼可以假設它一直在一個線程上運行,或者是無顧慮地在沒有任何準備工作的情況下直接運行在有許多線程的環境中。

你不是在寫一個Go程式使用C庫中的一些邏輯,取而代之的是你在寫一個Go程式,它必須與一段容易衝突的、很難被取代的、很難協商的、不顧慮你的問題的C代碼共存。

終日乾乾
翻譯於 4個月前

1人頂

頂 翻譯的不錯哦!

部署變得更複雜

對於普通讀者來說,任何關於Go的描述都要包含至少以下詞彙中的一點:

簡單,靜態二進位

這是Go的法寶,它引領Go成為了遠離虛擬機器和運行管理的典型代表。使用cgo,你就要放棄這些。

根據你的環境,把你的Go項目打成一個deb或rpm包,並且假設你其他的依賴也封裝好了,把它們加進安裝依賴,然後把問題從作業系統的包管理中拋出,這也許是可行的。但是這幾個構建和部署程式的重要改變就像 go build && scp一樣倉促直白。

編譯一個完全靜態Go程式是可行的,但是如果你的項目中包含了cgo那將是絕不簡單的,其後果將影響一整個構建和部署的生命週期。

請明智地選擇

要明確,我不是說你不應該使用cgo。但是在你做這筆交易之前,請仔細考慮你同時要放棄的Go的優點。

相關文章:

  1. Go 1.1的交叉編譯介紹

  2. Go 1.5的交叉編譯

  3. 交叉編譯變得更完整在Go 1.5中

  4. Go的交叉編譯介紹

終日乾乾
翻譯於 4個月前

1人頂

頂 翻譯的不錯哦!

本文中的所有譯文僅用於學習和交流目的,轉載請務必註明文章譯者、出處、和本文連結
我們的翻譯工作遵照 CC 協議,如果我們的工作有侵犯到您的權益,請及時聯絡我們

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.