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