這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
個人覺得goroutine是Go並行設計的核心,goroutine是協程,但比線程佔用更少。golang對並發的處理採用了協程的技術。golang的goroutine就是協程的實現。
十幾個goroutine可能體現在底層就是五六個線程,Go語言內部幫你實現了這些goroutine之間的記憶體共用。執行goroutine只需極少的棧記憶體(大概是4~5KB),當然會根據相應的資料伸縮也就是說,當傳輸資料多的情況下佔用量可能會高但是使用過後會自動進行縮小。也正因為如此,可同時運行成千上萬個並發任務。goroutine比thread更易用、更高效、更輕便。
不要通過共用記憶體來通訊,而應該通過通訊來共用記憶體。golang解決方案是訊息傳遞機制,訊息的傳遞就是通過channel來實現的。
採用別人的說法:
寄件者角度:對於同一個通道,發送操作(協程或者函數中的),在接收者準備好之前是阻塞的。如果chan中的資料無人接收,就無法再給通道傳入其他資料。因為新的輸入無法在通道非空的情況下傳入。所以發送操作會等待 chan 再次變為可用狀態:就是通道值被接收時(可以傳入變數)。
接收者角度:對於同一個通道,接收操作是阻塞的(協程或函數中的),直到寄件者可用:如果通道中沒有資料,接收者就阻塞了。
結果就是:如果Channel滿了,就阻塞寫,如果Channel空了,就阻塞讀
package main import ( "fmt" ) //此方法是對管道進行讀取 func c(i chan int) { fmt.Println(<-i) } func main() { out := make(chan int) //對管道進行發送操作 out <- 2 go c(out) }
這裡會報死結的錯誤
package main import ( "fmt" ) //此方法是對管道進行讀取 func c(i chan int) { fmt.Println(<-i) } func main() { out := make(chan int) //在發送操作之前進行管道讀取操作 //注意的地方是:作為發送方,在準備讀取之前管道是堵塞的。 go c(out) //對管道進行發送操作 out <- 2 }