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