導語
Go語言(也稱為Golang)是google在2009年推出的一種編譯型編程語言。相對于大多數(shù)語言,golang具有編寫并發(fā)或網(wǎng)絡交互簡單赃绊、豐富的數(shù)據(jù)類型岂昭、編譯快等特點,比較適合于高性能车伞、高并發(fā)場景择懂。本文主要基于筆者的親身實踐和總結,介紹golang的一些特性另玖,重點介紹并發(fā)的實現(xiàn)和使用困曙,希望能引發(fā)讀者一些啟發(fā)或興趣。
1谦去、Golang簡介
Go語言(也稱為Golang)是google在2009年推出的一種編譯型編程語言慷丽。相對于大多數(shù)語言,golang具有編寫并發(fā)或網(wǎng)絡交互簡單鳄哭、豐富的數(shù)據(jù)類型要糊、編譯快等特點,比較適合于高性能妆丘、高并發(fā)場景锄俄。2015年度的TIOBE指數(shù)計算機語言份額排名中,golang排在60+名勺拣,19年7月已上升到16名奶赠。
筆者曾于15年上半年在2個實際項目中引入golang 1.3,代碼量大概在3000行左右药有,最大的體會是并發(fā)編程入門容易毅戈。本文將以1.3來介紹,不過golang團隊更新太快,19年最新版本已到了1.12竹祷,不過核心設計思想與1.3并無大差異谈跛。
眾所周知,曾經在很長一段時間里塑陵,google保持著一個傳統(tǒng)感憾,允許員工擁有20%自由時間來開發(fā)實驗性項目,可惜現(xiàn)在該制度已經廢棄令花。golang正是由一個強大團隊利用這20%時間開發(fā)的阻桅。這里有必要介紹一下該團隊的核心成員,個個來頭不小兼都,都是計算機領域大神級人物嫂沉。最大牌的當屬B和C語言設計者、Unix和Plan 9創(chuàng)始人扮碧、1983年圖靈獎獲得者Ken Thompson趟章,其以70+歲高齡,不知道在golang實際開發(fā)中撰了多少代碼......另外慎王,這份名單中還包括了Unix核心成員Rob Pike蚓土、java HotSpot虛擬機和js v8引擎的開發(fā)者Robert Griesemer、Memcached作者Brad Fitzpatrick赖淤,等等蜀漆。
OK,進入正題咱旱,筆者結合個人整理和思考确丢,依次介紹golang幾個值得一說的特性和精髓,如果讀者能從中受到某些啟發(fā)吐限,就足夠了鲜侥。
2、并發(fā)編程
通過實踐毯盈,筆者認為golang在并發(fā)編程方面比絕大多數(shù)語言要簡潔不少剃毒,這一點是其最大亮點之一,也是其在未來進入高并發(fā)高性能場景的重要籌碼搂赋。
不同于傳統(tǒng)的多進程或多線程赘阀,golang的并發(fā)執(zhí)行單元是一種稱為goroutine的協(xié)程。協(xié)程這個概念已被引入到不少語言中脑奠,比如golang基公、python、lua等宋欺。協(xié)程經常被理解為輕量級線程轰豆,一個線程可以包含多個協(xié)程胰伍,共享堆不共享棧。協(xié)程間一般由應用程序顯式實現(xiàn)調度酸休,上下文切換無需下到內核層骂租,高效不少。協(xié)程間一般不做同步通訊斑司,而golang中實現(xiàn)協(xié)程間通訊有兩種:1)共享內存型渗饮,即使用全局變量+mutex鎖來實現(xiàn)數(shù)據(jù)共享;2)消息傳遞型宿刮,即使用一種獨有的channel機制進行異步通訊互站。
由于在共享數(shù)據(jù)場景中會用到鎖,再加上GC僵缺,其并發(fā)性能有時不如異步復用IO模型胡桃,因此相對于大多數(shù)語言來說,golang的并發(fā)編程簡單比并發(fā)性能更具賣點磕潮。
2.1翠胰、示例說明
下面是一段用golang寫的并發(fā)程序:
package main
import {
"fmt"
"runtime"
"time"
}
var MULTICORE int
func main() {
MULTICORE = runtime.NumCPU() //計算出本地的cpu核總數(shù)
//指定MULTICORE個核來運行
//這里沒有設置cpu親和性,所以各個線程會在任意cpu核上跑揉抵,同一個線程也可能會不斷跳到不同核上運行
runtime.GOMAXPROCS(MULTICORE)
// 啟動MULTICORE個goroutine來執(zhí)行test()
for i := 0; i < MULTICORE; i++ {
go test()
}
// sleep 10s是為了讓主進程等待所有goroutine都運行退出
time.Sleep(10*time.Second)
}
func test() {
for i := 0; i < 10; i++ {
fmt.Printf("test\n")
}
}
可以看出亡容,啟動一個goroutine很容易,只需要在(匿名)函數(shù)前面加個go關鍵字就行冤今,還能夠指定運行核數(shù),以期充分利用機器的計算能力茂缚。
2.2戏罢、底層實現(xiàn)
golang相較于傳統(tǒng)語言,為了更好適應現(xiàn)代多核脚囊、高并發(fā)場景龟糕,獨創(chuàng)了自己的協(xié)程模型,采用m:n模型悔耘,即m個gorountine(簡稱為G)映射到n個用戶態(tài)上下文(簡稱為P)上讲岁,一個P向上維護多個G組成的一個隊列,一個P向下與一個內核態(tài)工作線程(簡稱為M)相綁定衬以。
完整文章見:https://github.com/star2478/golang-wiki/wiki/%E6%B5%85%E8%B0%88Go%E8%AF%AD%E8%A8%80