Hi,你們好,我是明哥。git
在本身學習 Golang 的這段時間裏,我寫了詳細的學習筆記放在個人我的微信公衆號 《Go編程時光》,對於 Go 語言,我也算是個初學者,所以寫的東西應該會比較適合剛接觸的同窗,若是你也是剛學習 Go 語言,不防關注一下,一塊兒學習,一塊兒成長。github
個人在線博客:http://golang.iswbm.com
個人 Github:github.com/iswbm/GolangCodingTimegolang
說到Go語言,不少沒接觸過它的人,對它的第一印象,必定是它從語言層面天生支持併發,很是方便,讓開發者能快速寫出高性能且易於理解的程序。編程
在 Python (爲Py爲例,主要是我比較熟悉,其餘主流編程語言也相似)中,併發編程的門檻並不低,你要學習多進程,多線程,還要掌握各類支持併發的庫 asyncio,aiohttp 等,同時你還要清楚它們之間的區別及優缺點,懂得在不一樣的場景選擇不一樣的併發模式。數組
而 Golang 做爲一門現代化的編程語言,它不須要你直面這些複雜的問題。在 Golang 裏,你不須要學習如何建立進程池/線程池,也不須要知道什麼狀況下使用多線程,何時使用多進程。由於你沒得選,也不須要選,它原生提供的 goroutine (也即協程)已經足夠優秀,可以自動幫你處理好全部的事情,而你要作的只是執行它,就這麼簡單。微信
一個 goroutine 自己就是一個函數,當你直接調用時,它就是一個普通函數,若是你在調用前加一個關鍵字 go
,那你就開啓了一個 goroutine。多線程
// 執行一個函數 func() // 開啓一個協程執行這個函數 go func()
一個 Go 程序的入口一般是 main 函數,程序啓動後,main 函數最早運行,咱們稱之爲 main goroutine
。併發
在 main 中或者其下調用的代碼中才可使用 go + func()
的方法來啓動協程。異步
main 的地位至關於主線程,當 main 函數執行完成後,這個線程也就終結了,其下的運行着的全部協程也無論代碼是否是還在跑,也得乖乖退出。async
所以以下這段代碼運行完,只會輸出 hello, world
,而不會輸出hello, go
(由於協程的建立須要時間,當 hello, world
打印後,協程還沒來得及並執行)
import "fmt" func mytest() { fmt.Println("hello, go") } func main() { // 啓動一個協程 go mytest() fmt.Println("hello, world") }
對於剛學習Go的協程同窗來講,可使用 time.Sleep 來使 main 阻塞,使其餘協程可以有機會運行徹底,但你要注意的是,這並非推薦的方式(後續咱們會學習其餘更優雅的方式)。
當我在代碼中加入一行 time.Sleep 輸出就符合預期了。
import ( "fmt" "time" ) func mytest() { fmt.Println("hello, go") } func main() { go mytest() fmt.Println("hello, world") time.Sleep(time.Second) }
輸出以下
hello, world hello, go
爲了讓你看到併發的效果,這裏舉個最簡單的例子
import ( "fmt" "time" ) func mygo(name string) { for i := 0; i < 10; i++ { fmt.Printf("In goroutine %s\n", name) // 爲了不第一個協程執行過快,觀察不到併發的效果,加個休眠 time.Sleep(10 * time.Millisecond) } } func main() { go mygo("協程1號") // 第一個協程 go mygo("協程2號") // 第二個協程 time.Sleep(time.Second) }
輸出以下,能夠觀察到兩個協程就如兩個線程同樣,併發執行
In goroutine 協程2號 In goroutine 協程1號 In goroutine 協程1號 In goroutine 協程2號 In goroutine 協程2號 In goroutine 協程1號 In goroutine 協程1號 In goroutine 協程2號 In goroutine 協程1號 In goroutine 協程2號 In goroutine 協程1號 In goroutine 協程2號 In goroutine 協程1號 In goroutine 協程2號 In goroutine 協程1號 In goroutine 協程2號 In goroutine 協程1號 In goroutine 協程2號 In goroutine 協程1號 In goroutine 協程2號
經過以上簡單的例子,是否是折服於Go的這種強大的併發特性,將同步代碼轉爲異步代碼,真的只要一個關鍵字就能夠了,也不須要使用其餘庫,簡單方便。
本篇只介紹了協程的簡單使用,真正的併發程序仍是要結合 信道 (channel)來實現。關於信道的內容,將在下一篇文章中介紹。
系列導讀
24. 超詳細解讀 Go Modules 前世此生及入門使用