Go非阻塞channel的常见写法
2019獨角獸企業重金招聘Python工程師標準>>>
????go作為一種天然支持并發的語言,它的并發操作特別簡單,如下:
package mainfunc hello(word string) {fmt.Println("hello, ", word) }func main() {word := "world"go hello(word)fmt.Println(word) }直接在需要并發的語句前加上關鍵字go即可,深入了解一下go關鍵字背后其實是執行了一個runtime.newproc()方法新生成一個goroutine來執行接下來的語句。那既然是生成了一個子協程,在日常編碼的過程中,就肯定會涉及到如何在主協程和子協程之間進行通信的問題。一般地,在go的多線程環境中,我們通常使用go的管道類型channel來實現通信,當數據在channel中時,同一時刻只有一個協程能夠訪問數據,避免了出現競爭的可能,從而保證了并發安全。
? ? 但是channel默認是一種阻塞類型,如果編碼的時候不注意代碼的順序,經常會導致程序出現死鎖的情況。如下代碼就華麗麗的遇到了死鎖:
func say(ch chan int) {ch <- 2 }func main() {ch := make(chan int)say(ch) print(<-ch) }那應該如何實現非阻塞的channel使用:
1. 使用go關鍵字,創建一個新的協程,讓管道的push和pop不在同一個協程中執行就可以避免死鎖。
func main() {ch := make(chan int)go say(ch) print(<-ch) }2. 使用有緩存的管道channel,初始化時給channel指定buffer大小,在管道內的數據小于等于buffer值時,不會阻塞;超過則阻塞;
func main() {ch := make(chan int, 1)say(ch) print(<-ch) }3. 使用select關鍵字,該關鍵字可以監控channel管道中的數據流動,有流動就會觸發相應的case,沒有流動select會一直阻塞,類似于switch.
func main() {ch := make(chan int)ch1 := make(chan int) go say(ch)select {case c := <-ch1:print(c)default:print("no answer")} }?
轉載于:https://my.oschina.net/u/3470972/blog/1581810
總結
以上是生活随笔為你收集整理的Go非阻塞channel的常见写法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (58) 在计算字段提供搜索功能
- 下一篇: 微信小程序自定义组件方案