在這章中將展示 Go 使用 channel 和 goroutine 開發(fā)并行程序的能力。goroutine 是 Go并發(fā)能力的核心要素。但是,goroutine 到底是什么?來自 [8]:
叫做 goroutine 是因為已有的短語——線程、協(xié)程、進程等等——傳遞了不準確的含義。goroutine 有簡單的模型:它是與其他 goroutine 并行執(zhí)行的,有著相同地址空間的函數(shù)。它是輕量的,僅比分配??臻g多一點點消耗。而初始時棧是很小的,所以它們也是廉價的,并且隨著需要在堆空間上分配(和釋放)。
goroutine 是一個普通的函數(shù),只是需要使用關鍵字 go 作為開頭。
http://wiki.jikexueyuan.com/project/learn-go-language/images/167.png" alt="pic" />
下面程序的思路來自 [20]。讓一個函數(shù)作為兩個 goroutine 執(zhí)行,goroutine 等待一段時間,然后打印一些內(nèi)容到屏幕。在第 14 和 15 行,啟動了 goroutine。main 函數(shù)等待足夠的長的時間,這樣每個 goroutine 會打印各自的文本到屏幕?,F(xiàn)在是在第 17 行等待 5 秒鐘,但實際上沒有任何辦法知道,當所有 goroutine 都已經(jīng)退出應當?shù)却嗑谩?/p>
http://wiki.jikexueyuan.com/project/learn-go-language/images/168.png" alt="pic" />
如果不等待 goroutine 的執(zhí)行(例如,移除第 17 行),程序立刻終止,而任何正在執(zhí)行的 goroutine 都會停止。為了修復這個,需要一些能夠同 goroutine 通訊的機制。這一機制通過 channels 的形式使用。channel 可以與 Unix sehll 中的雙向管道做類比:可以通過它發(fā)送或者接收值。這些值只能是特定的類型:channel 類型。定義一個 channel時,也需要定義發(fā)送到 channel 的值的類型。注意,必須使用 make 創(chuàng)建 channel:
ci := make(chan i n t )
cs := make(chan s t r i n g )
cf := make(chan i n t e r f a c e { })
創(chuàng)建 channel ci 用于發(fā)送和接收整數(shù),創(chuàng)建 channel cs 用于字符串,以及 channel cf 使用了空接口來滿足各種類型。向 channel 發(fā)送或接收數(shù)據(jù),是通過類似的操作符完成的:<-. 具體作用則依賴于操作符的位置:
http://wiki.jikexueyuan.com/project/learn-go-language/images/169.png" alt="pic" />
將這些放到實例中去。
http://wiki.jikexueyuan.com/project/learn-go-language/images/170.png" alt="pic" />
0 .定義 c 作為 int 型的 channel。就是說:這個 channel 傳輸整數(shù)。注意這個變量是全局的,這樣 goroutine 可以訪問它;
這里仍然有一些丑陋的東西;不得不從 channel 中讀取兩次(第 14 和 15 行)。在這個例子中沒問題,但是如果不知道有啟動了多少個 goroutine 怎么辦呢?這里有另一個 Go 內(nèi)建的關鍵字:select。通過 select(和其他東西)可以監(jiān)聽 channel 上輸入的數(shù)據(jù)。
在這個程序中使用 select,并不會讓它變得更短,因為運行的 goroutine 太少了。移除第 14 和 15 行,并用下面的內(nèi)容替換它們:
http://wiki.jikexueyuan.com/project/learn-go-language/images/171.png" alt="pic" />
現(xiàn)在將會一直等待下去。只有當從 channel c 上收到多個響應時才會退出循環(huán) L。
雖然 goroutine 是并發(fā)執(zhí)行的,但是它們并不是并行運行的。如果不告訴 Go 額外的東西,同一時刻只會有一個 goroutine 執(zhí)行。利用 runtime.GOMAXPROCS(n) 可以設置 goroutine 并行執(zhí)行的數(shù)量。來自文檔:
GOMAXPROCS 設置了同時運行的 CPU 的最大數(shù)量,并返回之前的設置。如 果 n < 1,不會改變當前設置。當調(diào)度得到改進后,這將被移除。
如果不希望修改任何源代碼,同樣可以通過設置環(huán)境變量 GOMAXPROCS 為目標值。
當在 Go 中用 ch := make(chan bool) 創(chuàng)建 chennel 時,bool 型的無緩沖 channel 會被創(chuàng)建。這對于程序來說意味著什么呢?首先,如果讀?。╲alue := <