周威學Go從入門到放棄第十篇(多執行緒)
阿新 • • 發佈:2018-12-22
go語言多執行緒開發特別容易入門,通過go關鍵字實現,程式碼如下:
package main import ( "fmt" "runtime" ) func say(s string) { for i := 0; i < 5; i++ { runtime.Gosched() fmt.Println(s) } } func main() { go say("world") //開一個新的Goroutines執行 say("hello") //當前Goroutines執行 } /usr/local/go/bin/go build [/Users/zhouwei/go] 成功: 程序退出程式碼 0. /Users/zhouwei/go/go [/Users/zhouwei/go] hello hello hello hello hello 成功: 程序退出程式碼 0.
從執行結果看,好像並沒有執行 go say("world") 的內容,也沒有報錯,原因是什麼?
估計是因為main主程速度太快,來不及執行就已經結束了,嘗試一下
package main import ( "fmt" "runtime" "time" ) func say(s string) { for i := 0; i < 5; i++ { runtime.Gosched() fmt.Println(s) } } func main() { go say("world") //開一個新的Goroutines執行 say("hello") //當前Goroutines執行 time.Sleep(time.Second) } /usr/local/go/bin/go build [/Users/zhouwei/go] 成功: 程序退出程式碼 0. /Users/zhouwei/go/go [/Users/zhouwei/go] hello hello hello hello world hello world world world world 成功: 程序退出程式碼 0.
從列印結果看,果然加了一個休眠一秒,有結果了。具體是不是因為這個原因.
- 當建立一個Go協程時,建立這個Go協程的語句立即返回。與函式不同,程式流程不會等待Go協程結束再繼續執行。程式流程在開啟Go協程後立即返回並開始執行下一行程式碼,忽略Go協程的任何返回值。
- 在主協程存在時才能執行其他協程,主協程終止則程式終止,其他協程也將終止。
執行緒通訊
go執行緒之間的通訊通過channel(看起來內部實現是個佇列)來實現的,看示例:
package main import ( . "fmt" ) //從列印結果看,猜測實現是一個佇列,先入先出 var ch chan int = make(chan int) func main() { go add(1, 2) Println(<-ch) //列印channel中的內容 Println(<-ch) //列印channel中的內容 } func add(a int, b int) int { ch <- a + b //把計算的結果存到channel中 ch <- 1 //把計算的結果存到channel中 return a + b } /usr/local/go/bin/go build [/Users/zhouwei/go] 成功: 程序退出程式碼 0. /Users/zhouwei/go/go [/Users/zhouwei/go] 3 1 成功: 程序退出程式碼 0.
結合示例1,2程式碼來看,channel是阻塞佇列機制,出channel中取資料,存資料都會阻塞,這也是為什麼能正常跑下去的原因(沒有因為1中所說太快直接不執行了)