Channel使用技巧

2022-01-15 01:16:22 字數 2494 閱讀 7102

前言

go協程一般使用channel(通道)通訊從而協調/同步他們的工作。合理利用go協程和channel能幫助我們大大提高程式的效能。本文將介紹一些使用channel的場景及技巧

場景一,使用channel返回運算結果

計算斐波那契數列,在學習遞迴時候這是個經典問題。現在我們不用遞迴實現,而是用channel返回計算得出的斐波那契數列。 計算前40個斐波那契數列的值,看下效率

package main

import (

"fmt"

"time"

)//計算斐波那契數列並寫到ch中

func fibonacci(n int, ch chan<- int)

close(ch)

}func main()

end := time.now()

delta := end.sub(start)

fmt.printf("took the time: %s\n", delta)

}

只花了7ms,效率是遞迴實現的100倍(主要是演算法效率問題)

fibonacci(33) is: 5702887

fibonacci(34) is: 9227465

fibonacci(35) is: 14930352

fibonacci(36) is: 24157817

fibonacci(37) is: 39088169

fibonacci(38) is: 63245986

fibonacci(39) is: 102334155

took the time: 8.0004ms

使用for-range讀取channel返回的結果十分便利。當channel關閉且沒有資料時,for迴圈會自動退出,無需主動監測channel是否關閉。close(ch)只針對寫資料到channel起作用,意思是close(ch)後,ch中不能再寫資料,但不影響從ch中讀資料

場景二,使用channel獲取多個並行方法中的乙個結果

假設程式從多個複製的資料庫同時讀取。只需要接收首先到達的乙個答案,query 函式獲取資料庫的連線切片並請求。並行請求每乙個資料庫並返**到的第乙個響應:

func query(conns conn, query string) result 

}(conn)

}return <- ch

}

場景三,響應超時處理

在呼叫遠端方法的時候,存在超時可能,超時後返回超時提示

func callwithtimeout(timeout time.duration) (int, error) } 

func call() <-chan int ()

return outch

}

同樣可以擴充套件到channel的讀寫操作

func readwithtimeout(ch <-chan int) (x int, err error) 

}func writewithtimeout(ch chan<- int, x int) (err error)

}

使用<-time.after()超時設定可能引發的記憶體洩露問題,可以看這篇文章

超時後使用context取消goroutine執行的方法,參考:

場景四,多工併發執行和順序執行

方法a和b同時執行,方法c等待方法a執行完後才能執行,main等待a、b、c執行完才退出

package main

import (

"fmt"

"time"

)func b(quit chan<- string)

func a(quit chan<- string, finished chan<- bool)

func c(quit chan<- string, finished <-chan bool)

func main()

正常執行我們得到以下結果

b crraied out

ba crraied out

ac crraied out

c

注意:最後從quit中讀資料不能使用for-range語法,不然程式會出現死鎖

for res := range quit
fatal error: all goroutines are asleep - deadlock!
原因很簡單,程式中quit通道沒有被close,a、b、c執行完了,go的主協程在for迴圈中阻塞了,所有go協程都阻塞了,進入了死鎖狀態

golang開發 channel使用

channel主要是用於多個goroutine之間通訊 channel是引用型別,需要實用make來建立channel,如下 make chan type,buffer chan type 通道的型別 buffer 是可選引數,代表通道緩衝區的大小 省略則代表無緩衝 向channel裡面寫入資料使用...

golang開發 channel使用

channel主要是用於多個goroutine之間通訊 channel是引用型別,需要實用make來建立channel,如下 make chan type,buffer chan type 通道的型別 buffer 是可選引數,代表通道緩衝區的大小 省略則代表無緩衝 向channel裡面寫入資料使用...

go中channel簡單使用

channel是go語言在語言級別提供的goroutine間的通訊機制。我們可以使用channel在兩個或者多個goroutine之間傳遞資訊。channel是程序內的通訊。channel分為帶緩衝的以及不帶緩衝的。ch make chan int 建立乙個不帶緩衝的channel。ch make ...