[go] chan close

close chan

  • close由发送端调用,在收到最后一个发送值后关闭管道(It should be executed only by the sender, never the receiver, and has the effect of shutting down the channel after the last sent value is received)
  • close管道后,所有从管道的读取会获得元素对应类型的零值(any receive from c will succeed without blocking, returning the zero value for the channel element.)
package main

import (
    "fmt"
    "time"
)

func main() {
    stop := make(chan struct{})

    go func() {
        select {
        case _, ok := <-stop:
            fmt.Println("stop 01: ", ok)
        }
    }()

    go func() {
        select {
        case _, ok := <-stop:
            fmt.Println("stop 02: ", ok)
        }
    }()

    stop <- struct{}{}
    close(stop)

    time.Sleep(time.Second * 2)

    _, ok := <-stop
    fmt.Println("stop chan: ", ok)
}
stop 02: true
stop 01: false
stop chan: false

结论:chan中发送的值被第二个协程读取,主协程和第一个协程的读取都返回了bool的零值(false)

  • 不允许给已关闭的chan发送值,见下例:

    package main
    
    func main() {
      stop := make(chan struct{})
      close(stop)
    
      stop <- struct{}{}
    }
    panic: send on closed channel
  • 给chan发送值,只能被读取一次

    package main
    
    import (
      "fmt"
      "time"
    )
    
    func main() {
      stop := make(chan struct{})
    
      go func() {
          select {
          case _, ok := <-stop:
              //stop = nil
              fmt.Println("stop 01: ", ok)
          }
      }()
    
      go func() {
          select {
          case _, ok := <-stop:
              fmt.Println("stop 02: ", ok)
          }
      }()
    
      stop <- struct{}{}
    
      time.Sleep(time.Second * 2)
    }
    stop 02: true

这里因为只给chan发送了一个值,所以只会退出一个协程(随机性)。

你可能感兴趣的:(gochannel)