你不知道的go channel

來源:互聯網
上載者:User

最近在開發過程當中遇到了幾個goroutine通訊的問題,我覺得這幾個問題非常具有代表性,因此拿出來和大家分享一下。

檢查channel是否關閉

開發過程當中有遇到這樣的一種情況,需要檢查channel是否關閉,如果關閉則不進行相應操作,否則會panic等現象。在golang的select文法當中,default分支可以解決上述問題,請看如下例子:

closechan := make(chan int,0)dchan := make(chan int,0)select{    case <- closechan:        fmt.Println("channel already closed.")        return    default:        fmt.Println("channel not closed, do your things")          dchan <- 1 //1}  go func(){     for{        select{          case data := <- dchan: //2             err := doSomeThing(data) //3             if err != nil /* some thing wrong*/ { //4               close(closechan) //5            }          }    }  }

上述的方式可以在處理dchan的資料的時候處理異常並不再接受來自dchan的資料。

但是我們需要考慮一種情況,如果在doSomeThing(data)的過程當中,出現異常(4),那麼不允許往dchan發送資料,並將closechan關閉。在(5)關閉closechan之後就不會再進入(1)的default流程了。

可是這還有問題,那就是如果doSomeThing(data)處理的過程當中,新來了一個資料進入到了dchan,那麼將會在(1)(2)處阻塞,當doSomeThing(data)處理完之後,還會多處理一次異常情況,也就是說在(5)處將會close(closechan)兩次,這樣會導致panic: close of closed channel,所以我們需要在(5)再寫一個相應的default處理邏輯:

go func(){    for{        select{            case data := <- dchan: //2            err := doSomeThing(data) //3                if err != nil /* some thing wrong*/ { //4                    select{                        case <-closechan:                        //do nothing                          return                        default:                          close(closechan) //5                    }                }           }    }}

檢查buffered-channel是否已滿

當我們在使用bufferd-channel的時候,我們可能需要檢查當前的channel是否已經滿了,因為我們可能不希望此時goroutine阻塞,所以可以採用如下的方式進行處理:

cc := make(chan int, 1)cc <- data1select {    case cc <- data2:        fmt.Println("data already en-channel")    default:        fmt.Println("cc was full")}

fan-in

在研究並發map的時候,會考慮到一種shard-map的實現方式,在讀取map中的值的時候,需要通過多個小map中擷取完整的map值,可以利用channel實現fan-in:

func fanIn(chans []chan int, out chan int) {    wg := sync.WaitGroup{}    wg.Add(len(chans))    for _, ch := range chans {        go func(ch chan int) {            for t := range ch {                out <- t            }            wg.Done()        }(ch)    }    wg.Wait()    close(out)}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.