go語言運(yùn)行源代碼 go語言 開源項(xiàng)目

如何編譯arm linux的go

Golang也就是Go語言,現(xiàn)在已經(jīng)發(fā)行到1.4.1版本了,語言特性優(yōu)越性和背后Google強(qiáng)大靠山什么的就不多說了。Golang的官方提供了多個(gè)平臺(tái)上的二進(jìn)制安裝包,遺憾的是并非沒有發(fā)布ARM平臺(tái)的二進(jìn)制安裝包。ARM平臺(tái)沒辦法直接從官網(wǎng)下載二進(jìn)制安裝包來安裝,好在Golang是支持多平臺(tái)并且開源的語言,因此可以通過直接在ARM平臺(tái)上編譯源代碼來安裝。整個(gè)過程主要包括編譯工具配置、獲取Golang源代碼、設(shè)置Golang編譯環(huán)境變量、編譯、配置Golang行環(huán)境變量等步驟。

網(wǎng)站建設(shè)哪家好,找成都創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了鑲黃免費(fèi)建站歡迎大家使用!

注:本文選用樹莓派做測(cè)試,因?yàn)闃漭墒腔贏RM平臺(tái)的。

1、編譯工具配置

據(jù)說下個(gè)版本的golang編譯工具要使用golang自己來寫,但目前還是使用C編譯工具的。因此,首先要配置好C編譯工具:

1.1 在Ubuntu或Debian平臺(tái)上可以使用sudo apt-get install gcc libc6-dev命令安裝,樹莓派的RaspBian系統(tǒng)是基于Debian修改的,所以可以使用這種方法安裝。

1.2 在RedHat或CentOS 6平臺(tái)上可以使用sudo yum install gcc libc-devel命令安裝。

安裝完成后可以輸入 gcc --version命令驗(yàn)證是否成功安裝。

2、獲取golang源代碼

2.1 直接從官網(wǎng)下載源代碼壓縮包。

golang官網(wǎng)提供golang的源代碼壓縮包,可以直接下載,最新的1.4.1版本源代碼鏈接:

2.2 使用git工具獲取。

golang使用git版本管理工具,也可以使用git獲取golang源代碼。推薦使用這個(gè)方法,因?yàn)橐院罂梢噪S時(shí)獲取最新的golang源代碼。

2.2.1 首先確認(rèn)ARM平臺(tái)上已經(jīng)安裝了git工具,可以使用git --version命令確認(rèn)。一般linux平臺(tái)都安裝了git,沒有的話可以自行安裝,不同平臺(tái)的安裝方法可以參考:

2.2.2 克隆遠(yuǎn)程golang的git倉庫到本地

在終端cd到你想要安裝golang的目錄,確保該目錄下沒有名為go的目錄。然后以下命令獲取代碼倉庫:

git clone

大陸地區(qū)可能會(huì)獲取失敗,在不翻墻的情況下我試了幾次都沒成功,原因大家都懂的。好在google已經(jīng)將golang也托管到github上面,所以也可以通過下面命令獲?。?/p>

git clone

視網(wǎng)絡(luò)情況,下載可能需要不少時(shí)間。我2M的帶寬花了將近兩個(gè)小時(shí)才下載完,雖然整個(gè)項(xiàng)目不過幾十兆= =

下載完成后,可以看到目錄下多了一個(gè)go目錄,里面即為golang的源代碼,在終端上執(zhí)行cd go命令進(jìn)入該目錄。

執(zhí)行下面命令檢出go1.4.1版本的源代碼,因?yàn)楝F(xiàn)在已經(jīng)有新的代碼提交上去了,最新的代碼可能不是最穩(wěn)定的:

git checkout go1.4.1

至此,最新1.4.1發(fā)行版的源代碼獲取完畢

3、設(shè)置golang的編譯環(huán)境變量

主要有GOROOT、GOOS、GOARCH、GOARM四個(gè)環(huán)境變量需要設(shè)置,先解釋四個(gè)環(huán)境變量的意義。

3.1 GOROOT

主要代表golang樹結(jié)構(gòu)目錄的路徑,也就是上面git檢出的go目錄。一般可以不用設(shè)置這個(gè)環(huán)境變量,因?yàn)榫幾g的時(shí)候默認(rèn)會(huì)以go目錄下src子目錄中的all.bash腳本運(yùn)行時(shí)的父目錄作為GOROOT的值。為了保險(xiǎn)起見,可以直接設(shè)置為go目錄的路徑。

3.2 GOOS和GOARCH

分別代表編譯的目標(biāo)系統(tǒng)和平臺(tái),可選值如下:

GOOS GOARCH

darwin 386

darwin amd64

dragonfly 386

dragonfly amd64

freebsd 386

freebsd amd64

freebsd arm

linux 386

linux amd64

linux arm

netbsd 386

netbsd amd64

netbsd arm

openbsd 386

openbsd amd64

plan9 386

plan9 amd64

solaris amd64

windows 386

windows amd64

需要注意的是這兩個(gè)值代表的是目標(biāo)系統(tǒng)和平臺(tái),而不是編譯源代碼的系統(tǒng)和平臺(tái)。樹莓派的RaspBian是linux系統(tǒng),所以這些GOOS設(shè)置為linux,GOARCH設(shè)置為arm。

3.3 GOARM

表示使用的浮點(diǎn)運(yùn)算協(xié)處理器版本號(hào),只對(duì)arm平臺(tái)有用,可選值有5,6,7。如果是在目標(biāo)平臺(tái)上編譯源代碼,這個(gè)值可以不設(shè)置,它會(huì)自動(dòng)判斷需要使用哪一個(gè)版本。

總結(jié)下來,在樹莓派上設(shè)置golang的編譯環(huán)境變量,可編輯$HOME/.bashrc文件,在末尾添加下面內(nèi)容:

export GOROOT=你的go目錄路徑

export GOOS=linux

export GOARCH=arm

編輯完后保存,執(zhí)行source ~/.bashrc命令讓修改生效。

4、編譯源代碼

環(huán)境變量配置完成自后就可以開始編譯源代碼。在go目錄下的src子目錄中,主要有all.bash和make.bash兩個(gè)腳本(另外還有兩個(gè)all.bat和make.bat腳本適用于window平臺(tái))。編譯實(shí)際上就是執(zhí)行其中一個(gè)腳本,兩者的區(qū)別在于all.bash在編譯完成后還會(huì)執(zhí)行一些測(cè)試套件。如果希望只編譯不測(cè)試,可以運(yùn)行make.bash腳本。使用cd命令進(jìn)入go下src目錄,執(zhí)行./all.bash或者./make.bash命令即可開始編譯。由于硬件情況不同,編譯耗費(fèi)的時(shí)間不同。在我的B型樹莓派編譯過程花費(fèi)了將近半個(gè)小時(shí),編譯完成后執(zhí)行的測(cè)試套件又花費(fèi)了差不多一個(gè)小時(shí),總共花費(fèi)了一個(gè)半小時(shí)左右。

5、配置golang運(yùn)行環(huán)境變量

編譯完成后,go目錄下會(huì)生成bin目錄,里面就是go的運(yùn)行腳本。為了以后使用方法,可以將這個(gè)bin路徑添加到PATH環(huán)境變量中。同樣編輯~/.bashrc文件,因?yàn)榍懊嬖O(shè)置過GOROOT環(huán)境變量指向go目錄了,所以只需要在末尾加上

export PATH=$PATH:$GOROOT/bin

保存后同樣執(zhí)行source ~/.bashrc命令讓環(huán)境變量生效。

至此,golang源代碼編譯安裝成功。執(zhí)行g(shù)o version應(yīng)該就能看到當(dāng)前golang的版本信息,表示編譯安裝成功。

Golang database/sql源碼分析

Gorm是Go語言開發(fā)用的比較多的一個(gè)ORM。它的功能比較全:

但是這篇文章中并不會(huì)直接看Gorm的源碼,我們會(huì)先從database/sql分析。原因是Gorm也是基于這個(gè)包來封裝的一些功能。所以只有先了解了database/sql包才能更加好的理解Gorm源碼。

database/sql 其實(shí)也是一個(gè)對(duì)于mysql驅(qū)動(dòng)的上層封裝?!眊ithub.com/go-sql-driver/mysql”就是一個(gè)對(duì)于mysql的驅(qū)動(dòng),database/sql 就是在這個(gè)基礎(chǔ)上做的基本封裝包含連接池的使用

下面這個(gè)是最基本的增刪改查操作

操作分下面幾個(gè)步驟:

因?yàn)镚orm的連接池就是使用database/sql包中的連接池,所以這里我們需要學(xué)習(xí)一下包里的連接池的源碼實(shí)現(xiàn)。其實(shí)所有連接池最重要的就是連接池對(duì)象、獲取函數(shù)、釋放函數(shù)下面來看一下database/sql中的連接池。

DB對(duì)象

獲取方法

釋放連接方法

連接池的實(shí)現(xiàn)有很多方法,在database/sql包中使用的是chan阻塞 使用map記錄等待列表,等到有連接釋放的時(shí)候再把連接傳入等待列表中的chan 不在阻塞返回連接。

之前我們看到的Redigo是使用一個(gè)chan 來阻塞,然后釋放的時(shí)候放入空閑列表,在往這一個(gè)chan中傳入struct{}{},讓程序繼續(xù) 獲取的時(shí)候再從空閑列表中獲取。并且使用的是鏈表的結(jié)構(gòu)來存儲(chǔ)空閑列表。

database/sql 是對(duì)于mysql驅(qū)動(dòng)的封裝,然而Gorm則是對(duì)于database/sql的再次封裝。讓我們可以更加簡單的實(shí)現(xiàn)對(duì)于mysql數(shù)據(jù)庫的操作。

golang unicode/utf8源碼分析

包 utf-8 實(shí)現(xiàn)的功能和常量用于文章utf8編碼,包含runes和utf8字節(jié)序列的轉(zhuǎn)換功能.在unicode中,一個(gè)中文占兩個(gè)字節(jié),utf-8中一個(gè)中文占三個(gè)字節(jié),golang默認(rèn)的編碼是utf-8編碼,因此默認(rèn)一個(gè)中文占三個(gè)字節(jié),但是golang中的字符串底層實(shí)際上是一個(gè)byte數(shù)組.

Output:

RuneSelf該值的字節(jié)碼值為128,在判斷是否是常規(guī)的ascii碼是使用。hicb字節(jié)碼值為191. FF 的對(duì)應(yīng)的字節(jié)碼為255。

計(jì)算字符串中的rune數(shù)量,原理:首先取出字符串的碼值,然后判斷是不是個(gè)小于128的,如果是小于則直接continue.rune個(gè)數(shù)++.

如果是個(gè)十六進(jìn)制f1.的則是無效字符,直接continue.rune個(gè)數(shù)++,也就是說一個(gè)無效的字符也當(dāng)成一個(gè)字長為1的rune.如果字符的碼值在first列表中的值和7按位的結(jié)果為其字長,比如上面示例中的 鋼 。其字長為三位,第一位的值為 233 .二進(jìn)制形式為 11101001 ;與7按位與后的值為0.從acceptRanges中取出的結(jié)果為{locb, hicb}。也就是標(biāo)識(shí) ox80 到 0xbf 之間的值。而結(jié)果n也就是直接size+3跳過3個(gè)字節(jié)后,rune個(gè)數(shù)++。其他函數(shù)的處理流程差不多,不再過多敘述。

示例:

ValidString返回值表明參數(shù)字符串是否是一個(gè)合法的可utf8編碼的字符串。

RuneCount返回參數(shù)中包含的rune數(shù)量,第一個(gè)例子中將 utf8.RuneCountInString ,改成該方法調(diào)用,返回的結(jié)果相同。錯(cuò)誤的和短的被當(dāng)成一個(gè)長一字節(jié)的rune.單個(gè)字符 H 就表示一個(gè)長度為1字節(jié)的rune.

該函數(shù)標(biāo)識(shí)參數(shù)是否以一個(gè)可編碼的rune開頭,上面的例子中,因?yàn)樽址且砸粋€(gè)ascii碼值在0-127內(nèi)的字符開頭,所以在執(zhí)行

first[p[0]] 時(shí),取到的是 p[0] 是72,在first列表中,127之前的值都相同都為 0xF0 ,十進(jìn)制標(biāo)識(shí)為240,與7按位與后值為0,所以,直接返回 true .

和FullRune類似,只是參數(shù)為字符串形式

如何創(chuàng)建,編譯,打包go語言的源代碼和工程

1.最簡單的方法:

public static String reverse1(String str)

{ return new StringBuffer(str).reverse().toString();

}

2.最常用的方法:

public static String reverse3(String s)

{ char[] array = s.toCharArray();

String reverse = ""; //注意這是空串,不是null

for (int i = array.length - 1; i = 0; i--)

reverse += array[i];

return reverse;

}

3.常用方法的變形:

public static String reverse2(String s)

{ int length = s.length();

String reverse = ""; //注意這是空串,不是null

for (int i = 0; i length; i++)

reverse = s.charAt(i) + reverse;//在字符串前面連接, 而非常見的后面

return reverse;

}

Go語言的開源項(xiàng)目

1.Docker項(xiàng)目

網(wǎng)址為 。

介紹:Docker是一種操作系統(tǒng)層面的虛擬化技術(shù),可以在操作系統(tǒng)和應(yīng)用程序之間進(jìn)行隔離,也可以稱之為容器。Docker可以在一臺(tái)物理服務(wù)器上快速運(yùn)行一個(gè)或多個(gè)實(shí)例。例如,啟動(dòng)一個(gè)Cent OS操作系統(tǒng),并在其內(nèi)部命令行執(zhí)行指令后結(jié)束,整個(gè)過程就像自己在操作系統(tǒng)一樣高效。

2.golang項(xiàng)目

網(wǎng)址為 。

介紹:Go語言的早期源碼使用C語言和匯編語言寫成。從Go 1.5版本自舉后,完全使用Go語言自身進(jìn)行編寫。Go語言的源碼對(duì)了解Go語言的底層調(diào)度有極大的參考意義,建議希望對(duì)Go語言有深入了解的讀者讀一讀。

3.Kubernetes項(xiàng)目

網(wǎng)址為 。

介紹:Google公司開發(fā)的構(gòu)建于Docker之上的容器調(diào)度服務(wù),用戶可以通過Kubernetes集群進(jìn)行云端容器集群管理。

4.etcd項(xiàng)目

網(wǎng)址為 。

介紹:一款分布式、可靠的KV存儲(chǔ)系統(tǒng),可以快速進(jìn)行云配置。

5.beego項(xiàng)目

網(wǎng)址為 。

介紹:beego是一個(gè)類似Python的Tornado框架,采用了RESTFul的設(shè)計(jì)思路,使用Go語言編寫的一個(gè)極輕量級(jí)、高可伸縮性和高性能的Web應(yīng)用框架。

6.martini項(xiàng)目

網(wǎng)址為 。

介紹:一款快速構(gòu)建模塊化的Web應(yīng)用的Web框架。

7.codis項(xiàng)目

網(wǎng)址為 Labs/codis。

介紹:國產(chǎn)的優(yōu)秀分布式Redis解決方案。

8.delve項(xiàng)目

網(wǎng)址為 。

介紹:Go語言強(qiáng)大的調(diào)試器,被很多集成環(huán)境和編輯器整合。

golang map源碼淺析

golang 中 map的實(shí)現(xiàn)結(jié)構(gòu)為: 哈希表 + 鏈表。 其中鏈表,作用是當(dāng)發(fā)生hash沖突時(shí),拉鏈法生成的結(jié)點(diǎn)。

可以看到, []bmap 是一個(gè)hash table, 每一個(gè) bmap是我們常說的“桶”。 經(jīng)過hash 函數(shù)計(jì)算出來相同的hash值, 放到相同的桶中。 一個(gè) bmap中可以存放 8個(gè) 元素, 如果多出8個(gè),則生成新的結(jié)點(diǎn),尾接到隊(duì)尾。

以上是只是靜態(tài)文件 src/runtime/map.go 中的定義。 實(shí)際上編譯期間會(huì)給它加料 ,動(dòng)態(tài)地創(chuàng)建一個(gè)新的結(jié)構(gòu):

上圖就是 bmap的內(nèi)存模型, HOB Hash 指的就是 top hash。 注意到 key 和 value 是各自放在一起的,并不是 key/value/key/value/... 這樣的形式。源碼里說明這樣的好處是在某些情況下可以省略掉 padding 字段,節(jié)省內(nèi)存空間。

每個(gè) bmap設(shè)計(jì)成 最多只能放 8 個(gè) key-value 對(duì) ,如果有第 9 個(gè) key-value 落入當(dāng)前的 bmap,那就需要再構(gòu)建一個(gè) bmap,通過 overflow 指針連接起來。

map創(chuàng)建方法:

我們實(shí)際上是通過調(diào)用的 makemap ,來創(chuàng)建map的。實(shí)際工作只是初始化了hmap中的各種字段,如:設(shè)置B的大小, 設(shè)置hash 種子 hash 0.

注意 :

makemap 返回是*hmap 指針, 即 map 是引用對(duì)象, 對(duì)map的操作會(huì)影響到結(jié)構(gòu)體內(nèi)部 。

使用方式

對(duì)應(yīng)的是下面兩種方法

map的key的類型,實(shí)現(xiàn)了自己的hash 方式。每種類型實(shí)現(xiàn)hash函數(shù)方式不一樣。

key 經(jīng)過哈希計(jì)算后得到hash值,共 64 個(gè) bit 位。 其中后B 個(gè)bit位置, 用來定位當(dāng)前元素落在哪一個(gè)桶里, 高8個(gè)bit 為當(dāng)前 hash 值的top hash。 實(shí)際上定位key的過程是一個(gè)雙重循環(huán)的過程, 外層循環(huán)遍歷 所有的overflow, 內(nèi)層循環(huán)遍歷 當(dāng)前bmap 中的 8個(gè)元素 。

舉例說明: 如果當(dāng)前 B 的值為 5, 那么buckets 的長度 為 2^5 = 32。假設(shè)有個(gè)key 經(jīng)過hash函數(shù)計(jì)算后,得到的hash結(jié)果為:

外層遍歷bucket 中的鏈表

內(nèi)層循環(huán)遍歷 bmap中的8個(gè) cell

建議先不看此部分內(nèi)容,看完后續(xù) 修改 map中元素 - 擴(kuò)容 操作后 再回頭看此部分內(nèi)容。

擴(kuò)容前的數(shù)據(jù):

等量擴(kuò)容后的數(shù)據(jù):

等量擴(kuò)容后,查找方式和原本相同, 不多做贅述。

兩倍擴(kuò)容后的數(shù)據(jù)

兩倍擴(kuò)容后,oldbuckets 的元素,可能被分配成了兩部分。查找順序如下:

此處只分析 mapaccess1 ,。 mapaccess2 相比 mapaccess1 多添加了是否找到的bool值, 有興趣可自行看一下。

使用方式:

步驟如下:

擴(kuò)容條件 :

擴(kuò)容的標(biāo)識(shí) : h.oldbuckets != nil

假設(shè)當(dāng)前定位到了新的buckets的3號(hào)桶中,首先會(huì)判斷oldbuckets中的對(duì)應(yīng)的桶有沒有被搬遷過。 如果搬遷過了,不需要看原來的桶了,直接遍歷新的buckets的3號(hào)桶。

擴(kuò)容前:

等量擴(kuò)容結(jié)果

雙倍擴(kuò)容會(huì)將old buckets上的元素分配到x, y兩個(gè)部key 1 B == 0 分配到x部分,key 1 B == 1 分配到y(tǒng)部分

注意: 當(dāng)前只對(duì)雙倍擴(kuò)容描述, 等量擴(kuò)容只是重新填充了一下元素, 相對(duì)位置沒有改變。

假設(shè)當(dāng)前map 的B == 5,原本元素經(jīng)過hash函數(shù)計(jì)算的 hash 值為:

因?yàn)殡p倍擴(kuò)容之后 B = B + 1,此時(shí)B == 6。key 1 B == 1, 即 當(dāng)前元素rehash到高位,新buckets中 y 部分. 否則 key 1 B == 0 則rehash到低位,即x 部分。

使用方式:

可以看到,每一遍歷生成迭代器的時(shí)候,會(huì)隨機(jī)選取一個(gè)bucket 以及 一個(gè)cell開始。 從前往后遍歷,再次遍歷到起始位置時(shí),遍歷完成。

網(wǎng)頁名稱:go語言運(yùn)行源代碼 go語言 開源項(xiàng)目
當(dāng)前鏈接:http://muchs.cn/article6/dossiig.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站營銷、定制開發(fā)、外貿(mào)網(wǎng)站建設(shè)網(wǎng)站策劃、網(wǎng)站改版網(wǎng)站導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)