您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Go語言中通道channel的示例分析,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
線程之間進行通信的時候,會因為資源的爭奪而產生竟態問題,為了保證數據交換的正確性,必須使用互斥量給內存進行加鎖,go語言并發的模型是CSP,提倡通過通信共享內存,而不是通過共享內存而實現通信,通道恰巧滿足這種需求。
channel
類似與一個隊列,滿足先進先出的規則,嚴格保證收發數據的順序,每一個通道只能通 過固定類型的數據如果通道進行大型結構體、字符串的傳輸,可以將對應的指針傳進去,盡量的節省空間
//定義一個通道對象使用,其中int可以換為自己需要的類型 var a chan int //初始化只有一個位置的通道(第一個參數代表通道類型,第二個參數代表通道有幾個位置) //位置存滿后新的數據將存不進來(阻塞) a = make(chan int,1)
取出數據使用操作符 <-操作符右是輸入變量,操作符左是通道代表數據流入通道內
代碼如下:
// 聲明一個通道 var a chan int a <- 5
取出數據也使用操作符 <-操作符右是通道,操作符左是接受變量
代碼如下:
//聲明一個通道類型 var a chan int fmt.Println("未初始化的通道", a) a = make(chan int) // wg.Add(1) go func(a chan int) { // defer wg.Done() for { x := <-a fmt.Println("接收到了數據:", x) } }(a)
如果通道重復關閉或者關閉一個沒有初始化的通道就會拋出錯誤
close(a)//a為待關閉的通道
在并發函數中一次關閉通道代碼如下:
// 互斥鎖對象 var once sync.Once //并發函數 //這個函數的目的是將a通道內數據乘以10發送到通道b內 func f2(a <-chan int, b chan<- int) { defer wg.Done() for { x, ok := <-a if !ok { break } fmt.Println(x) b <- x * 10 } // 確保b通道只關閉一次 once.Do(func() { close(b) }) }
var b <-chan int
var b chan<- int
示例函數:
//單項通道一般做函數參數,作為一種規范防止通道混用 //此函數完成的功能是將a內的數據乘以10放入通道b內 func f2(a <-chan int, b chan<- int) { for { x, ok := <-a if !ok { break } fmt.Println(x) b <- x * 10 } }
channel | nil未初始化 | 空通道 | 滿通道 | 非空 |
---|---|---|---|---|
接收 | 阻塞 | 阻塞 | 接收值 | 接收值 |
發送 | 阻塞 | 發送值 | 阻塞 | 發送值 |
關閉 | panic | 關閉成功 | 關閉成功 | 關閉成功 |
關閉后返回的數據 | panic | 返回0值 | 數據讀完后返回零值 | 數據讀完返回零值 |
注意以下情況:
在使用通道的時候,從以上表格可知有時會進入阻塞狀態,結合waitGroup,如果在主函數等待使用通道的函數執行結束,而使用通道的函數并且通道陷入阻塞狀態,如果有其他函數對其進行喚醒則不會死鎖,如果沒有其他函數可以對其進行喚醒則會拋出死鎖異常。
關于“Go語言中通道channel的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。