Go 語(yǔ)言教程
Go 語(yǔ)言支持并發(fā),我們只需要通過(guò) go 關(guān)鍵字來(lái)開啟 goroutine 即可。
goroutine 是輕量級(jí)線程,goroutine 的調(diào)度是由 Golang 運(yùn)行時(shí)進(jìn)行管理的。
goroutine 語(yǔ)法格式:
go 函數(shù)名( 參數(shù)列表 )
例如:
go f(x, y, z)
開啟一個(gè)新的 goroutine:
f(x, y, z)
Go 允許使用 go 語(yǔ)句開啟一個(gè)新的運(yùn)行期線程, 即 goroutine,以一個(gè)不同的、新創(chuàng)建的 goroutine 來(lái)執(zhí)行一個(gè)函數(shù)。 同一個(gè)程序中的所有 goroutine 共享同一個(gè)地址空間。
執(zhí)行以上代碼,你會(huì)看到輸出的 hello 和 world 是沒(méi)有固定先后順序。因?yàn)樗鼈兪莾蓚€(gè) goroutine 在執(zhí)行:
world hello hello world world hello hello world world hello
通道(channel)是用來(lái)傳遞數(shù)據(jù)的一個(gè)數(shù)據(jù)結(jié)構(gòu)。
通道可用于兩個(gè) goroutine 之間通過(guò)傳遞一個(gè)指定類型的值來(lái)同步運(yùn)行和通訊。操作符 <-
用于指定通道的方向,發(fā)送或接收。如果未指定方向,則為雙向通道。
ch <- v // 把 v 發(fā)送到通道 ch v := <-ch // 從 ch 接收數(shù)據(jù) // 并把值賦給 v
聲明一個(gè)通道很簡(jiǎn)單,我們使用chan關(guān)鍵字即可,通道在使用前必須先創(chuàng)建:
ch := make(chan int)
注意:默認(rèn)情況下,通道是不帶緩沖區(qū)的。發(fā)送端發(fā)送數(shù)據(jù),同時(shí)必須有接收端相應(yīng)的接收數(shù)據(jù)。
以下實(shí)例通過(guò)兩個(gè) goroutine 來(lái)計(jì)算數(shù)字之和,在 goroutine 完成計(jì)算后,它會(huì)計(jì)算兩個(gè)結(jié)果的和:
輸出結(jié)果為:
-5 17 12
通道可以設(shè)置緩沖區(qū),通過(guò) make 的第二個(gè)參數(shù)指定緩沖區(qū)大?。?/p>
ch := make(chan int, 100)
帶緩沖區(qū)的通道允許發(fā)送端的數(shù)據(jù)發(fā)送和接收端的數(shù)據(jù)獲取處于異步狀態(tài),就是說(shuō)發(fā)送端發(fā)送的數(shù)據(jù)可以放在緩沖區(qū)里面,可以等待接收端去獲取數(shù)據(jù),而不是立刻需要接收端去獲取數(shù)據(jù)。
不過(guò)由于緩沖區(qū)的大小是有限的,所以還是必須有接收端來(lái)接收數(shù)據(jù)的,否則緩沖區(qū)一滿,數(shù)據(jù)發(fā)送端就無(wú)法再發(fā)送數(shù)據(jù)了。
注意:如果通道不帶緩沖,發(fā)送方會(huì)阻塞直到接收方從通道中接收了值。如果通道帶緩沖,發(fā)送方則會(huì)阻塞直到發(fā)送的值被拷貝到緩沖區(qū)內(nèi);如果緩沖區(qū)已滿,則意味著需要等待直到某個(gè)接收方獲取到一個(gè)值。接收方在有值可以接收之前會(huì)一直阻塞。
執(zhí)行輸出結(jié)果為:
1 2
Go 通過(guò) range 關(guān)鍵字來(lái)實(shí)現(xiàn)遍歷讀取到的數(shù)據(jù),類似于與數(shù)組或切片。格式如下:
v, ok := <-ch
如果通道接收不到數(shù)據(jù)后 ok 就為 false,這時(shí)通道就可以使用 close() 函數(shù)來(lái)關(guān)閉。
執(zhí)行輸出結(jié)果為:
0 1 1 2 3 5 8 13 21 34