關於GOLANG的chan

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

GOLANG CHAN

chan是golang中非常重要的一個東西,用來做goroutine的通訊,因為golang程式必然會有多個goroutine,如何同步這些goroutine就很重要了。

使用chan時有幾個心得:

  1. 首先,永遠是符號<-進行讀取或者寫入,譬如v,ok := <-c是讀取,而c <- v是寫入。
  2. 其次,讀取時,如果沒有ok,也是可以讀取的。不過如果closed也是能讀的,沒有賦值而已;如果要知道是否closed得加ok,也就是除非chan永遠不關閉,否則讀取應該用v,ok := <-c而不是用v := <-c的方式。
  3. 再次,不能向closed的chan寫入,所以一般寫入時需要用一個訊號的chan(一般buffer為1),來判斷是否寫入或者放棄,用select判斷是寫入成功了,還是正在關閉需要放棄寫入。
  4. 最後,如果closed後,chan有資料,ok還是true的,直到chan沒有資料了才false。

讀寫Chan

永遠是符號<-進行讀取或者寫入,譬如v,ok := <-c是讀取,而c <- v是寫入。

c := make(chan int, 1)c <- 10 // 寫入chanv := <- c // 從chan中讀取

下面的例子判斷chan是否關閉:

c := make(chan int, 1)c <- 10v,ok := <- c // 讀取,v=10,ok=trueclose(c)v,ok := <- c // 讀取,v=0,ok=false

如果寫不進去就丟棄,可以用select:

c := make(chan int, 1)select {case c <- 10: // c中放入了10,因為chan的buffer為1default: }select {case c <- 11:default: // c中只有10,沒有11}select {case v,ok := <- c:    // 讀出來一個,v=10, ok=truedefault:}select {case v,ok := <- c:default: // 沒有可讀的,走這個分支}

還可以用逾時之類的,也是一個chan,time.After(xxx)返回的就是chan。

判斷closed

讀取時,如果沒有ok,也是可以讀取的。不過如果closed也是能讀的,沒有賦值而已;如果要知道是否closed得加ok,也就是除非chan永遠不關閉,否則讀取應該用v,ok := <-c而不是用v := <-c的方式。

c := make(chan int, 1)c <- 10close(c)v := <- c // c=10,讀取出來一個v = <- c // c=0,實際上沒有讀出來,但是判斷不了
c := make(chan int, 1)c <- 10close(c)v,ok := <- c // c=10,ok=true,讀取出來一個v,ok = <- c // c=0,ok=false,實際上沒有讀出來

寫入chan

不能向closed的chan寫入,所以一般寫入時需要用一個訊號的chan,來判斷是否寫入或者放棄,用select判斷是寫入成功了,還是正在關閉需要放棄寫入。

type TcpListeners struct {    conns  chan *net.TCPConn    closing chan bool    wait *sync.WaitGroup}func NewTcpListeners(addrs []string) (v *TcpListeners, err error) {    v = &TcpListeners{        addrs:     addrs,        conns:     make(chan *net.TCPConn),        closing:   make(chan bool, 1),        wait:      &sync.WaitGroup{},    }    return}// Listen at addrs format as netowrk://laddr, for example,// tcp://:1935, tcp4://:1935, tcp6://1935, tcp://0.0.0.0:1935func (v *TcpListeners) ListenTCP() (err error) {    for _, addr := range v.addrs {        vs := strings.Split(addr, "://")        network, laddr := vs[0], vs[1]        if l, err := net.Listen(network, laddr); err != nil {            return nil,err        } else {            v.listeners = append(v.listeners, l.(*net.TCPListener))        }    }    v.wait.Add(len(v.listeners))    for i, l := range v.listeners {        addr := v.addrs[i]        go func(l *net.TCPListener, addr string) {            defer v.wait.Done()            for {                var conn *net.TCPConn                if conn, err = l.AcceptTCP(); err != nil {                    return                }                select {                case v.conns <- conn:                case c := <-v.closing:                    v.closing <- c                    conn.Close()                }            }        }(l, addr)    }    return}func (v *TcpListeners) AcceptTCP() (c *net.TCPConn, err error) {    var ok bool    if c,ok = <- v.conns; !ok {        return nil, ListenerDisposed    }    return}func (v *TcpListeners) Close() (err error) {    // unblock all listener internal goroutines    v.closing <- true    // interrupt all listeners.    for _, v := range v.listeners {        if r := v.Close(); r != nil {            err = r        }    }    // wait for all listener internal goroutines to quit.    v.wait.Wait()    // clear the closing signal.    _ = <-v.closing    // close channels to unblock the user goroutine to AcceptTCP()    close(v.conns)    return}

這樣在關閉Listener時,不會導致ListenTCP的goroutine寫入closed的chan而導致錯誤。

Closed Chan

如果closed後,chan有資料,ok還是true的,直到chan沒有資料了才false。

c := make(chan int, 1)c <- 10close(c)v,ok := <- c // v=10,ok=true,雖然c關閉了,但是有資料,ok依然是truev,ok <- c // v=0,ok=false,讀失敗了。
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.