自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Go與C在嵌入式應(yīng)用開發(fā)中的對(duì)比

譯文 精選
開發(fā) 開發(fā)工具 后端
迫在眉睫的交付期限,不切實(shí)際的進(jìn)度計(jì)劃,無(wú)休止的按時(shí)開發(fā)并發(fā)布應(yīng)用程序的壓力,并且還要保證質(zhì)量。是不是很熟悉的感覺?

迫在眉睫的交付期限,不切實(shí)際的進(jìn)度計(jì)劃,無(wú)休止的按時(shí)開發(fā)并發(fā)布應(yīng)用程序的壓力,并且還要保證質(zhì)量。是不是很熟悉的感覺?對(duì)于嵌入式開發(fā)團(tuán)隊(duì)來(lái)說(shuō),盡快實(shí)現(xiàn)嵌入式應(yīng)用程序的發(fā)布是一個(gè)很重要的事項(xiàng)。那么,有沒有一個(gè)捷徑既能快速交付應(yīng)用程序,同時(shí)又能優(yōu)先確保應(yīng)用質(zhì)量和安全性呢?在這一思路下,OTA軟件更新管理軟件開發(fā)團(tuán)隊(duì) Mender.io,就Mender的嵌入式客戶端和服務(wù)器端部分的開發(fā),做了一個(gè)最佳編程軟件評(píng)估,Go、C和C++入圍。最終,Go被選中。下面,通過評(píng)估過程中優(yōu)劣判斷對(duì)比,分析一下Go能夠勝出的原因。

盡管這種選擇帶有一定的主觀性,但Go確實(shí)是一種非常高效的嵌入式開發(fā)語(yǔ)言,尤其是涉及到網(wǎng)絡(luò)編程時(shí)。網(wǎng)絡(luò)編程在某些時(shí)候是遍布每個(gè)連接的設(shè)備或應(yīng)用程序的。Go語(yǔ)言由Google創(chuàng)建,起初是為了滿足Google開發(fā)人員的需求,用于面對(duì)其生態(tài)系統(tǒng)中爆炸式增長(zhǎng)的復(fù)雜性。因此,GO語(yǔ)言自面世就遵循了高效編譯、高效執(zhí)行和易于編程這三個(gè)原則,這是它較之其他主流語(yǔ)言的優(yōu)勢(shì)。

但是,需要強(qiáng)調(diào)的是,Go并不能被視為C語(yǔ)言的替代品。很多時(shí)候C語(yǔ)言仍是無(wú)可替代的,例如實(shí)時(shí)操作系統(tǒng)和設(shè)備驅(qū)動(dòng)程序的開發(fā)。

嵌入式開發(fā)的嚴(yán)格要求

建立架構(gòu)后,Mender產(chǎn)品工程團(tuán)隊(duì)開始評(píng)估哪種語(yǔ)言最適合開發(fā) Mender應(yīng)用程序。該系統(tǒng)由兩部分組成:一是在嵌入式設(shè)備上運(yùn)行的客戶端,二是連接各客戶端的中心服務(wù)器。因此,對(duì)該語(yǔ)言有以下幾個(gè)要求:

  • 客戶端應(yīng)用程序運(yùn)行于嵌入式設(shè)備之上,要求編譯的二進(jìn)制文件盡可能地??;
  • 能夠與Linux的嵌入式發(fā)行版本Yocto兼容。
  • 客戶端要易于安裝,不需要依賴外部項(xiàng)和庫(kù)。
  • 由于需要在不同的設(shè)備上運(yùn)行,故該語(yǔ)言須具備跨體系結(jié)構(gòu)編譯能力。
  • Mender客戶端應(yīng)用程序運(yùn)行的設(shè)備會(huì)是IoT或網(wǎng)絡(luò)設(shè)備,因此該語(yǔ)言需要具備訪問網(wǎng)絡(luò)庫(kù)能力。

此外還有一些非功能性要求:

  • 此語(yǔ)言能被部門大多數(shù)程序員理解掌握;
  • 盡可能無(wú)難度地實(shí)現(xiàn)與現(xiàn)有的C語(yǔ)言編寫的應(yīng)用程序之間共享和重用已有代碼,客戶端和服務(wù)器應(yīng)用程序之間亦可重用代碼。
  • 還要考慮開發(fā)速度——團(tuán)隊(duì)時(shí)刻面臨著快速添加新功能的需求和壓力。

Go、C 和 C++的比較如圖 1 所示。Go之所以被選擇,主要是由于它支持緩沖區(qū)溢出保護(hù)、自動(dòng)內(nèi)存管理、使用標(biāo)準(zhǔn)數(shù)據(jù)容器,以及對(duì)JSON、HTTP和SSL/TLS庫(kù)的集成支持。

 1:Go、C 和 C++的功能表比較

評(píng)估團(tuán)隊(duì)使用Yocto創(chuàng)建一個(gè)完善的定制Linux映像,比較了原始的映像體積較之具有網(wǎng)絡(luò)堆棧的映像體積,以及最終應(yīng)用程序?qū)懭胗诚竦姆绞?。在這一評(píng)估過程中,Go是可以與C,C++和C++ / Qt相媲美的。由于Go應(yīng)用程序可以靜態(tài)編譯為單個(gè)二進(jìn)制文件,因此它并不需要任何額外的虛擬環(huán)境(比如Java除了二進(jìn)制文件之外還需要虛擬機(jī)),Go代碼在設(shè)備上運(yùn)行也不需要依賴其他項(xiàng)。

 2:Go 與其他編程語(yǔ)言進(jìn)行比較

比較GO和C

選中Go語(yǔ)言進(jìn)行開發(fā),還源于它極其豐富的標(biāo)準(zhǔn)庫(kù)。這一優(yōu)勢(shì)有助于開發(fā)進(jìn)程的加快,特別是與C語(yǔ)言相比。Go語(yǔ)言從C、C++和Python繼承了許多元素,包括表達(dá)式語(yǔ)句,控制流語(yǔ)句,數(shù)據(jù)結(jié)構(gòu),接口,指針,引用傳遞概念,參數(shù)解析語(yǔ)法,字符串處理和垃圾回收機(jī)制。憑借其優(yōu)化的編譯器,Go 可在嵌入式設(shè)備上實(shí)現(xiàn)代碼本地運(yùn)行。

當(dāng)然,Go語(yǔ)言不可避免的會(huì)有一些缺點(diǎn),后面也將提及。但瑕不掩瑜,這并不影響Go語(yǔ)言明顯的優(yōu)勢(shì),比如在開發(fā)速度和語(yǔ)言構(gòu)建方面的便利性。這些對(duì)于評(píng)估團(tuán)隊(duì)的選擇也有所影響,下面逐一來(lái)看。

Go和C代碼體積比較

在代碼體積方面,Go不如C輕便,這是它為數(shù)不多的缺點(diǎn)之一。以最簡(jiǎn)單的應(yīng)用程序“hello world”為例,在Go使用內(nèi)置printIn函數(shù)編寫,去除調(diào)試符號(hào)后,它的大小為剛剛超過600KB(代碼段1)。如果將fmt包及其依賴項(xiàng)包括在內(nèi),則大小將增至 1.5 MB(代碼段 2)。

與之相比較,使用C語(yǔ)言的話,如果是構(gòu)建一個(gè)動(dòng)態(tài)鏈接庫(kù),則它的大小只有8KB。但如果使用靜態(tài)鏈接庫(kù),則大小將增加到800 KB以上,比較令人意外的是它比Go二進(jìn)制文件(代碼段3)還要大。

代碼段1:最基本的 Go語(yǔ)言 “hello world” 代碼:

package main 
func main() {
println("hello world")
}

$ go build
> 938K
$ go build -ldflags ‘-s -w’
> 682K
$ go build & strip
> 623K

代碼段2:標(biāo)準(zhǔn)的Go語(yǔ)言“hello world” 代碼:

package main
import "fmt"
func main() {
fmt.Println("hello world")
}
$ go build
> 1,5M

代碼段3:C語(yǔ)言“hello world” 代碼:

#include <stdio.h> 
int main(void)
{
printf("hello world\n");
return 0;
}
$ gcc main.c
> 8,5K
$ ldd a.out
> linux-vdso.so.1
> libc.so.6
> /lib64/ld-linux-x86-64.so.2
$ gcc -static main.c
> 892K
$ gcc -static main.c & strip
> 821K

Go與C的運(yùn)行速度比較

編譯后的Go代碼運(yùn)行起來(lái)通常會(huì)比C語(yǔ)言的可執(zhí)行文件慢。Go是具備完全垃圾收集機(jī)制的,生來(lái)就影響了運(yùn)行速度。使用C語(yǔ)言時(shí)可以精確地指定為變量分配的內(nèi)存的位置,可以具體到該變量是在棧上還是在堆上;而使用Go時(shí),編譯器會(huì)自動(dòng)處理將變量分配在何處。程序員可以看到變量的分配位置 (go build -gcflags -m),但不能強(qiáng)制編譯器僅使用摸個(gè)位置比如棧。

但是,速度不是僅限于上述,還要考慮到編譯速度和開發(fā)速度。Go提供了極快的編譯速度。比如,15,000行代碼Go客戶端僅需1.4秒就能編譯完畢。并且,Go是為并發(fā)執(zhí)行(goroutines和channels)而設(shè)計(jì)的,前面闡述過的豐富的標(biāo)準(zhǔn)庫(kù)能夠涵蓋大部分基本需求,因此有利于程序員開發(fā)速度加快。

編譯和交叉編譯

有兩種編譯器可供程序員選擇使用:原始編譯器叫做gc ,默認(rèn)安裝程序自帶,由Google編寫和維護(hù)。第二種叫做gccgo,是GCC的前端。gccgo使用起來(lái)編譯速度極快,大型模塊通常幾秒鐘就可以編譯完畢。如前所述,Go默認(rèn)是以靜態(tài)庫(kù)編譯,這樣就可以無(wú)需額外依賴項(xiàng)或虛擬機(jī)創(chuàng)建單個(gè)二進(jìn)制文件。可以使用-linkshared標(biāo)志創(chuàng)建和使用共享庫(kù)。通常,Go不需要構(gòu)建文件,如需構(gòu)建則可通過使用簡(jiǎn)單的“go build”命令執(zhí)行,高級(jí)復(fù)雜的構(gòu)建可以使用Makefile。這里是在Mender使用的Makefile。

除此之外,Go在交叉編譯方面支持眾多操作系統(tǒng)和架構(gòu)。圖 3 示例了 Go 支持的各種操作系統(tǒng)和平臺(tái)。

圖3  Go 支持的各種操作系統(tǒng)和平臺(tái)

 Go 中調(diào)試和測(cè)試

許多開發(fā)人員使用GDB監(jiān)視程序執(zhí)行情況。對(duì)于高并發(fā)Go應(yīng)用程序,使用GDB調(diào)試時(shí)會(huì)出現(xiàn)一些問題。萬(wàn)幸的是,一個(gè)名為 Delve 的專用Go調(diào)試器是可以完美使用的,確保了即使是只會(huì)使用GDB的開發(fā)人員大多數(shù)情形下也能輕松調(diào)試。

Go代碼中添加測(cè)試和單元測(cè)試十分簡(jiǎn)單,測(cè)試是內(nèi)置在Go語(yǔ)言中的——只需創(chuàng)建一個(gè)帶有“test”后綴的文件,為函數(shù)添加測(cè)試前綴,導(dǎo)入測(cè)試包,然后運(yùn)行“go test”。所有測(cè)試就將自動(dòng)從源中獲取并相應(yīng)執(zhí)行。

并發(fā)支持

Go語(yǔ)言對(duì)并發(fā)支持特別友好。它有兩個(gè)內(nèi)置調(diào)度機(jī)制:goroutines和channels。goroutines是輕量級(jí)線程,僅僅2 kB。創(chuàng)建非常容易:只需要在函數(shù)前面添加“go”關(guān)鍵字,它就會(huì)同時(shí)執(zhí)行。Go有自己的內(nèi)部調(diào)度器,可以根據(jù)需要將goroutines多路復(fù)用到OS線程中。channels是用于在 goroutine 之間交換消息的“管道”,可以是阻塞的,也可以是通行的。

靜態(tài)和動(dòng)態(tài)庫(kù):Go語(yǔ)言中的的 C 代碼

Go有許多鮮為人知的功能,允許程序員使用特殊標(biāo)志將指令發(fā)送給編譯器、連接器和工具鏈的其他部分。其中包括-buildmode和-linkshared標(biāo)志,二者皆可用于為Go和C代碼段創(chuàng)建并使用靜態(tài)和動(dòng)態(tài)庫(kù)。通過特定標(biāo)志的組合,程序員可以使用生成的C語(yǔ)言頭文件創(chuàng)建靜態(tài)或動(dòng)態(tài)庫(kù),這些頭文件以后可由C代碼調(diào)用。

是的,沒錯(cuò)!使用Go,可以調(diào)用C代碼并擁有兩全其美的功能。Go發(fā)行版包含一個(gè)工具名為cgo,可以執(zhí)行C代碼,這使得重用程序員自己的或系統(tǒng)的C庫(kù)成為可能。實(shí)際上,Cgo以及C系統(tǒng)庫(kù)的間接引用是十分常見的。某些情況下,標(biāo)準(zhǔn)C庫(kù)例程就是由Go語(yǔ)言構(gòu)造語(yǔ)法本身從Go實(shí)例中選取。

例如,在Unix系統(tǒng)上使用網(wǎng)絡(luò)包時(shí),很有可能會(huì)選擇基于cgo的解析器。它會(huì)調(diào)用C庫(kù)例程 ( getaddrinfo和 getnameinfo)來(lái)解析無(wú)法使用本機(jī)Go解析器的名稱(例如在 OS X上直接 DNS 調(diào)用被禁用時(shí));另一種常見情況則是使用系統(tǒng)/用戶程序包時(shí)。如果想跳過構(gòu)建cgo部件,程序員可以通過osusergo和netgo標(biāo)記 (go build -tags osusergo,netgo)或使用CGO_ENABLED=0變量完全禁用 cgo。

將C和Go混合在一起時(shí),還需要注意一些比較棘手的事情。由于Go是有垃圾回收機(jī)制的而 C不是,所以如果在Go代碼中使用了任何分配在C代碼堆棧上的C變量,都必須在 Go 中聲明釋放。

通過使用接口生成工具(SWIG)來(lái)實(shí)現(xiàn),C++也可以在Go代碼中使用。SWIGC能夠?qū)o與C++以及Python等語(yǔ)言融合在一起。

Go的優(yōu)點(diǎn)大于缺陷

從以往的經(jīng)驗(yàn)可以得出Go既有優(yōu)點(diǎn)也有缺陷。就負(fù)面因素來(lái)講,社區(qū)中有很多外部庫(kù),但良莠不齊,需要非常小心辨別使用。隨著Go語(yǔ)言的成熟和廣泛采用,這種情況正在迅速改善。

此外,當(dāng)Go代碼中存在一些C綁定時(shí),事情通常會(huì)變得更為復(fù)雜,尤其是交叉編譯,如果不導(dǎo)入整個(gè)C交叉編譯基礎(chǔ)結(jié)構(gòu),就難以完成。

總體而言,使用Go進(jìn)行嵌入式開發(fā)還是有很多優(yōu)點(diǎn)的。從C或Python(或二者兼有)過渡到Go并在短期內(nèi)使用是快速簡(jiǎn)單而可行的。Go語(yǔ)言提供了非常優(yōu)秀的工具和一個(gè)包含100多個(gè)軟件包的標(biāo)準(zhǔn)庫(kù)。程序員可以輕松控制和設(shè)置運(yùn)行參數(shù),例如,要使用的操作系統(tǒng)線程數(shù)(GOMAXPROCS),打開或關(guān)閉垃圾回收 (GOGC=off)等。庫(kù)以及代碼可以在服務(wù)器和客戶端開發(fā)團(tuán)隊(duì)之間輕松共享,就像文中提及的實(shí)例那樣。

這樣說(shuō)可能會(huì)引起爭(zhēng)論,但一致的編碼標(biāo)準(zhǔn)事實(shí)上加快了開發(fā)速度。無(wú)論程序員要檢查的代碼是什么,它看起來(lái)是一致的。無(wú)需耗費(fèi)時(shí)間在思考使用哪種編碼標(biāo)準(zhǔn)上。

工程師們開發(fā)了一些嵌入式Go應(yīng)用程序的演示,可以應(yīng)用在新興設(shè)備上(例如Beaglebone Black或Raspberry Pi):其中一個(gè)名為“恒溫器”,基于Beaglebone硬件,使用紅外距離、溫度和濕度傳感器,并可以通過 Web界面讀取所有傳感器讀數(shù);還有一個(gè)是基于PRi的機(jī)器人汽車,帶有攝像頭,可以通過Web界面進(jìn)行控制。喜歡就去享受吧!

譯者介紹

張哲剛,51CTO社區(qū)編輯,系統(tǒng)運(yùn)維工程師,國(guó)內(nèi)較早一批硬件評(píng)測(cè)及互聯(lián)網(wǎng)從業(yè)者,曾入職阿里巴巴。十余年IT項(xiàng)目管理經(jīng)驗(yàn),具備復(fù)合知識(shí)技能,曾參與多個(gè)網(wǎng)站架構(gòu)設(shè)計(jì)、電子政務(wù)系統(tǒng)開發(fā),主導(dǎo)過某地市級(jí)招生考試管理平臺(tái)運(yùn)維工作。

原文標(biāo)題:??Comparing Go vs. C in embedded applications??,作者:Marcin Pasinski

責(zé)任編輯:莫奇 來(lái)源: 51CTO
相關(guān)推薦

2009-04-11 15:12:24

2009-05-28 13:39:13

Windows CE

2009-07-08 14:32:10

GTK+嵌入式Linux

2017-08-03 23:40:49

無(wú)操作系統(tǒng)嵌入式開發(fā)

2014-06-19 13:59:55

2011-01-14 13:13:23

嵌入式Linux開發(fā)

2009-07-17 16:06:59

ARM嵌入式開發(fā)

2016-09-01 13:56:11

PythonC語(yǔ)言C++

2010-01-21 09:15:05

Linux嵌入式文件系

2018-05-02 16:34:56

EAF嵌入式框架

2011-07-01 16:43:26

微軟MVP微軟嵌入式金融行業(yè)

2010-01-06 09:53:08

嵌入式

2010-01-13 09:15:35

嵌入式

2010-06-09 11:33:50

嵌入式開發(fā)微軟Windows 7

2021-10-26 21:50:10

Rust嵌入式開發(fā)

2011-07-05 15:42:02

QT 嵌入式 Embedded

2022-03-11 15:44:11

嵌入式開發(fā)技巧技術(shù)

2012-07-30 14:13:11

Linux 2.6內(nèi)核嵌入式

2011-07-01 16:25:40

微軟MVP嵌入式智能家居

2011-01-06 15:11:09

嵌入式linux
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)