這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
Go 提供了一個關鍵字go
用於執行並行作業的關鍵字 所以說Go從語言層面上就支援了並發
其中go 關鍵字啟動的是一個協程這裡並非線程 協程是輕量級的 有可能10幾個協程下對應了5,6個線程go語言自動幫我們管理
其實和java中的線程池 我個人覺得還是很類似的
只不過java中的線程池有多種實現方式 如schedule single fix buffer 各有不同的使用情境
目前我還是不太清楚這種替我們管理線程的方式是好或不好 畢竟不是大牛 先用著再說吧
Goroutine - 協程
通過go關鍵字就可以直接啟動一個協程
Channel - 協程間通訊的通道
管道應該很好理解 就和Java裡面的IO流管道式一個道理一邊進一邊出
在Go中 如果調用了內建函數close關閉之後 便無法再向管道中寫入資料但是仍然可以繼續讀取資料
做漢堡包的人--簡稱廚師
比如麥當勞裡面買漢堡包 廚師後台做好了一個漢堡包 如果是在一個比較大的麥當勞店裡會有一台機器,廚師把漢堡放到機器中然後繼續做自己的事,機器負責把這個做好的漢堡運送到前面的那個保溫的透明箱子裡 ,也就是我們每回點餐時都能看到的那個 裡面放了很多漢堡 雞腿 雞塊啥的 ,如果有人點了漢堡 前台收銀員就會從這裡面拿一個漢堡出來給顧客 然後繼續做自己的事
這整個過程如果按照Go裡面的說法就是完成了協程之間的通訊 廚師就是協程1 前台收銀員就是協程2 而中間所有的部分都是Channel
通過程式碼範例更容易懂
channel := make(chan int) 這樣就聲明了一個阻塞式的無緩衝的通道
chan 是關鍵字 代表我要建立一個通道
int則代表該通道所能接受的資料類型為int
那麼如果有兩個A,B兩個協程 在放入和取出資料時都只能用int類型的資料進行通訊
如 取資料 <- channel 放資料 channel <- 1
協程之間可以通過在通道中放入-取出資料的方式進行通訊
用代碼展示下無阻賽的Channel是如何在協程之間實現通訊
樣本 並發計算
package mainimport ("fmt")func sum(arr []int,c chan int){num := 0for _,v := range arr {num += v}//放入資料到通道中 --- 如此一來 主協程中一發現通道中有資料就會立刻取出資料了c <- num}func main() {//建立一個通訊通道c := make(chan int)slice := []int {1,2,3,4,5,6,7,8,9,10}//啟動協程 1go sum(slice[0:len(slice)/2],c)//啟動協程 2go sum(slice[len(slice)/2:],c)//阻塞式 接受來自 協程1,2的返回結果num1, num2 := <- c, <- cfmt.Println(num1, num2, num1+num2)}