Go語言中的通道channel詳情
一、Go語言通道基礎概念
1.channel產生背景
線程之間進行通信的時候,會因為資源的爭奪而產生竟態(tài)問題,為了保證數據交換的正確性,必須使用互斥量給內存進行加鎖,go語言并發(fā)的模型是CSP,提倡通過通信共享內存,而不是通過共享內存而實現通信,通道恰巧滿足這種需求。
2.channel工作方式
channel類似與一個隊列,滿足先進先出的規(guī)則,嚴格保證收發(fā)數據的順序,每一個通道只能通 過固定類型的數據如果通道進行大型結構體、字符串的傳輸,可以將對應的指針傳進去,盡量的節(jié)省空間
二、通道使用語法
1.通道的聲明與初始化
?? ?//定義一個通道對象使用,其中int可以換為自己需要的類型 ?? ?var a chan int ? ?? ?//初始化只有一個位置的通道(第一個參數代表通道類型,第二個參數代表通道有幾個位置) ?? ?//位置存滿后新的數據將存不進來(阻塞) ?? ?a = make(chan int,1)
2.將數據放入通道內
- 取出數據使用操作符 <-操作符右是輸入變量,操作符左是通道代表數據流入通道內
代碼如下:
? ?// 聲明一個通道 ?? ?var a chan int ?? ??? ?a <- 5
3.從通道內取出數據
- 取出數據也使用操作符 <-操作符右是通道,操作符左是接受變量
代碼如下:
?//聲明一個通道類型
?? ?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)4.關閉通道close
如果通道重復關閉或者關閉一個沒有初始化的通道就會拋出錯誤
?close(a)//a為待關閉的通道
在并發(fā)函數中一次關閉通道代碼如下:
// 互斥鎖對象
var once sync.Once
//并發(fā)函數
//這個函數的目的是將a通道內數據乘以10發(fā)送到通道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)
?? ?})
}三、單項通道及通道的狀態(tài)分析
1.單項輸出通道
?? ?var b <-chan int
2.單項輸入通道
?? ?var b chan<- int
示例函數:
//單項通道一般做函數參數,作為一種規(guī)范防止通道混用
//此函數完成的功能是將a內的數據乘以10放入通道b內
func f2(a <-chan int, b chan<- int) {
?? ?for {
?? ??? ?x, ok := <-a
?? ??? ?if !ok {
?? ??? ??? ?break
?? ??? ?}
?? ??? ?fmt.Println(x)
?? ??? ?b <- x * 10
?? ?}
}3.通道的狀態(tài)
| channel | nil未初始化 | 空通道 | 滿通道 | 非空 |
|---|---|---|---|---|
| 接收 | 阻塞 | 阻塞 | 接收值 | 接收值 |
| 發(fā)送 | 阻塞 | 發(fā)送值 | 阻塞 | 發(fā)送值 |
| 關閉 | panic | 關閉成功 | 關閉成功 | 關閉成功 |
| 關閉后返回的數據 | panic | 返回0值 | 數據讀完后返回零值 | 數據讀完返回零值 |
四、通道死鎖原因分析
注意以下情況:
在使用通道的時候,從以上表格可知有時會進入阻塞狀態(tài),結合waitGroup,如果在主函數等待使用通道的函數執(zhí)行結束,而使用通道的函數并且通道陷入阻塞狀態(tài),如果有其他函數對其進行喚醒則不會死鎖,如果沒有其他函數可以對其進行喚醒則會拋出死鎖異常。
總結:
通道將數據隔離在每一份通道內,在并發(fā)的情況下可以很好的使用數據,當然要熟悉通道阻塞的幾種情況,避免死鎖異常。
到此這篇關于Go語言中的通道channel詳情的文章就介紹到這了,更多相關Go語言中的通道channel內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
深入探討Go語言中的map是否是并發(fā)安全以及解決方法
這篇文章主要來和大家探討?Go?語言中的?map?是否是并發(fā)安全的,并提供三種方案來解決并發(fā)問題,文中的示例代碼講解詳細,需要的可以參考一下2023-05-05

