博客 / 詳情

返回

[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發送了一個值,所以只會退出一個協程(隨機性)。

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.