一.goroutine簡介
- Golang中最迷人的一個優勢就是從語言層面就支持併發
- 在Golang中的goroutine(協程)相似於其餘語言的線程
- 併發和並行
- 並行(parallelism)指不一樣的代碼片斷同時在不一樣的物理處理器上支持
- 併發(concurrency)指同時管理多個事情,物理處理器上可能運行某個內容一半後就處理其餘事情
- 在通常看來併發的性能要好於並行.由於計算機的物理資源是固定的,較少的,而程序須要執行的內容是不少的.因此併發是」以較少的資源去去作更多事情」
- 幾種主流併發模型
- 多線程,每一個線程只處理一個請求,只有請求結束後,對應的線程纔會接收下一個請求.這種模式在高併發下,性能開銷極大.
- 基於回調的異步IO.在程序運行過程當中可能產生大量回調致使維護成本加大,程序執行流程也不便於思惟
- 協程.不須要搶佔式調用,能夠有效提高線程任務的併發性,彌補了多線程模式的缺點;Golang在語言層面就支持,而其餘語言不多支持(內核態與用戶態)
- goroutine的語法
- 表達式能夠是一條語句
- 表達式也能夠是函數,函數返回值即便有,也無效,當函數執行完成此goroutine自動結束
go 表達式
二. 代碼示例
- 對比屢次調用函數和使用goroutine的效果
package main
import "fmt"
import "time"
func main() {
//正常調用,輸出3遍1 2 3 4 5(每一個數字後換行)
//for i:=1; i<=3; i++ {
// go demo()
//}
/*
添加go關鍵字後發現控制檯什麼也沒有輸出
緣由:把demo()設置到協程後沒等到函數執行,主
線程執行結束
*/
for i := 1; i <= 3; i++ {
go demo(i)
}
}
func demo(index int) {
for i := 1; i <= 5; i++ {
fmt.Printf("第%d次執行,i的值爲:%d\n", index, i)
}
}
- 添加休眠等待goroutine執行結束
- 這種方式很大的問題就是休眠時間,若是休眠時間設置太小,可能goroutine並無執行完成,若是休眠時間設置過大,影響程序執行執行.找到的本次執行的休眠時間,下次程序執行時這個休眠時間可能」過大」或」太小"
- 經過程序運行結果發現每次執行結果都不必定是同樣的,由於每一個demo()都是併發執行
package main
import "fmt"
import "time"
func main() {
//正常調用,輸出3遍1 2 3 4 5(每一個數字後換行)
//for i:=1; i<=3; i++ {
// go demo()
//}
/*
添加go關鍵字後發現控制檯什麼也沒有輸出
緣由:把demo()設置到協程後沒等到函數執行,主
線程執行結束
*/
for i := 1; i <= 3; i++ {
go demo(i)
}
/*
添加休眠,讓主線程等待協程執行結束.
具體休眠時間須要根據計算機性能去估計
次數沒有固定值
*/
time.Sleep(3e9)
fmt.Println("程序執行結束")
}
func demo(index int) {
for i := 1; i <= 5; i++ {
fmt.Printf("第%d次執行,i的值爲:%d\n", index, i)
}
}