Golang對并發(fā)的支持相對簡單囱挑,采用的是Goroutine的機(jī)制酱床,類似于協(xié)程腹殿。
采用Go關(guān)鍵字就能實(shí)現(xiàn)旨枯。
Goroutine 基礎(chǔ)
第一種情況
func main() {
for i := 0; i < 10; i++ {
go func(i int) {
fmt.Println(i)
}(i)
}
}
猜猜以上代碼的輸出蹬昌,結(jié)果是什么都不輸出。
為什么呢攀隔,明明我用go開啟了10個并發(fā)協(xié)程為什么什么都不輸出呢皂贩?
原因:當(dāng)走完for循環(huán)的時候栖榨,main方法就結(jié)束了。這個時候 程序就會釋放所有資源明刷。所以go創(chuàng)建的并發(fā)func并不會執(zhí)行婴栽。
第二種情況
func main() {
wg := new(sync.WaitGroup)
wg.Add(10)
for i := 0; i < 10; i++ {
go func(i int) {
defer wg.Done()
fmt.Println(i)
}(i)
}
wg.Wait()
}
先介紹一下sync.WaitGroup,點(diǎn)開可以看文檔辈末。
wg.Add(delta int)方法就是來設(shè)定應(yīng)等待的線程的數(shù)量愚争。
wg.Done() Done方法減少WaitGroup計(jì)數(shù)器的值,應(yīng)在線程的最后執(zhí)行挤聘。
wg.Wait() Wait方法阻塞直到WaitGroup計(jì)數(shù)器減為0轰枝。
這樣寫的目的就是讓main方法阻塞。
那么輸出的話就會很隨機(jī)组去,因?yàn)槟阋膊恢滥膫€線程會先跑完鞍陨。
附加runtime方法
func main() {
runtime.GOMAXPROCS(2)
wg := new(sync.WaitGroup)
wg.Add(10)
for i := 0; i < 10; i++ {
go func(i int) {
defer wg.Done()
if i == 3 {
runtime.Goexit()
}
fmt.Println(i)
}(i)
}
wg.Wait()
}
runtime.GOMAXPROCS(2) OMAXPROCS設(shè)置可同時執(zhí)行的最大CPU數(shù),來實(shí)現(xiàn)多核多線程并行添怔。
runtime.Goexit() Goexit終止調(diào)用它的go程湾戳。其它go程不會受影響。Goexit會在終止該go程前執(zhí)行所有defer的函數(shù)广料。
Goroutine通信 --> Channel
Channel的設(shè)計(jì)為了實(shí)現(xiàn)Goruntine直接的通信砾脑。值得一提的是Channel是值類型,這點(diǎn)需要注意艾杏。
//創(chuàng)建
chan = make(chan int)
使用channel在倆goroutine間傳遞消息
func main() {
runtime.GOMAXPROCS(4)
ch := make(chan int)
go add(1, 2, ch)
go printAaddB(ch)
}
func add(a int, b int, ch chan int) {
ch <- a + b
}
func printAaddB(ch chan int) {
fmt.Println(<-ch)
}
這樣便實(shí)現(xiàn)了chennel傳遞消息韧衣。
參考
以上內(nèi)容如有錯誤,請指出购桑。
Go 學(xué)習(xí)筆記 第四版 雨痕
Go 中文文檔