Go channel 关闭和广播

简介: Go channel 关闭和广播

Go channel 关闭和广播


Dont Communicate by sharing memory, sharing memory by communicate.
不要通过共享内存的方式通讯,要通过通讯的方式共享内存

Channel 基本概念


一个通道相当于 FIFO 的队列, 通道中各个元素之间都是严格按照发送的顺序队列,先发送的队列一定会被先接收,元素值的发送和传输和发送都使用到操作符 <-

channel 的关闭


  • 向关闭的 channel 发送数据, 会导致 panic
package main
import (
 "fmt"
 "sync"
 "testing"
)
func dataProducer(ch chan int, wg *sync.WaitGroup) {
 go func() {
  for i := 0; i < 11; i++ {
   ch <- i
  }
  wg.Done()
 }()
}
func dataConsumer(ch chan int , wg *sync.WaitGroup) {
 go func () {
  for i := 0; i < 10; i++ {
   data := <- ch
   fmt.Println(data)
  }
  close(ch)
  wg.Done()
 }()
}
func TestCloseChanner(t *testing.T) {
 var wg sync.WaitGroup
 ch := make(chan int)
 wg.Add(1)
 dataProducer(ch, &wg)
 wg.Add(1)
 dataConsumer(ch, &wg)
 wg.Wait()
}


运行结果


GOROOT=C:\Go #gosetup
GOPATH=D:\GoWorkSpace #gosetup
C:\Go\bin\go.exe test -c -o C:\Users\wangm\AppData\Local\Temp\___channel_close_test_go.exe GoProject/src/main/gobase/channel #gosetup
C:\Go\bin\go.exe tool test2json -t C:\Users\wangm\AppData\Local\Temp\___channel_close_test_go.exe -test.v -test.run ^\QTestCloseChanner\E$ #gosetup
=== RUN   TestCloseChanner
0
1
2
3
4
5
6
7
8
9
panic: send on closed channel
goroutine 20 [running]:
GoProject/src/main/gobase/channel.dataProducer.func1(0xc0000862a0, 0xc0000942b0)
 D:/GoWorkspaces/GoProject/src/main/gobase/channel/channel_close_test.go:12 +0x4a
created by GoProject/src/main/gobase/channel.dataProducer
 D:/GoWorkspaces/GoProject/src/main/gobase/channel/channel_close_test.go:10 +0x50
Process finished with exit code 1


  • v, ok <- ch; ok 为 bool 值, true 表示正常接收,false 表示通道关闭
  • 所有的 channel 接收者都会在 channel 关闭时,立刻从阻塞等待中返回且上述 ok 值 为 false 。这个广播机制被利用,进行多个订阅同时发送信号。

image.png

package main
import (
 "fmt"
 "sync"
 "testing"
)
func dataProducer(ch chan int, wg *sync.WaitGroup) {
 go func() {
  for i := 0; i < 10; i++ {
   ch <- i
  }
  close(ch)
  wg.Done()
 }()
}
func dataConsumer(ch chan int , wg *sync.WaitGroup) {
 go func () {
  for i := 0; i < 10; i++ {
   if data, ok := <- ch; ok {
    fmt.Println(data)
   } else {
    break
   }
  }
  wg.Done()
 }()
}
func TestCloseChanner(t *testing.T) {
 var wg sync.WaitGroup
 ch := make(chan int)
 wg.Add(1)
 dataProducer(ch, &wg)
 wg.Add(1)
 dataConsumer(ch, &wg)
 wg.Wait()
}

运行结果


GOROOT=C:\Go #gosetup
GOPATH=D:\GoWorkSpace #gosetup
C:\Go\bin\go.exe test -c -o C:\Users\wangm\AppData\Local\Temp\___channel_close_test_go.exe GoProject/src/main/gobase/channel #gosetup
C:\Go\bin\go.exe tool test2json -t C:\Users\wangm\AppData\Local\Temp\___channel_close_test_go.exe -test.v -test.run ^\QTestCloseChanner\E$ #gosetup
=== RUN   TestCloseChanner
0
1
2
3
4
5
6
7
8
9
--- PASS: TestCloseChanner (0.00s)
PASS
Process finished with exit code 0


测试代码


package main
import (
 "fmt"
 "sync"
 "testing"
)
func dataProducer(ch chan int, wg *sync.WaitGroup) {
 go func() {
  for i := 0; i < 10; i++ {
   ch <- i
  }
  close(ch)
  wg.Done()
 }()
}
func dataConsumer(ch chan int , wg *sync.WaitGroup) {
 go func () {
  for i := 0; i < 11; i++ {
   data := <- ch
   fmt.Println(data)
  }
  wg.Done()
 }()
}
func TestCloseChanner(t *testing.T) {
 var wg sync.WaitGroup
 ch := make(chan int)
 wg.Add(1)
 dataProducer(ch, &wg)
 wg.Add(1)
 dataConsumer(ch, &wg)
 wg.Wait()
}


运行结果:


GOPATH=D:\GoWorkSpace #gosetup
C:\Go\bin\go.exe test -c -o C:\Users\wangm\AppData\Local\Temp\___channel_close_test_go.exe GoProject/src/main/gobase/channel #gosetup
C:\Go\bin\go.exe tool test2json -t C:\Users\wangm\AppData\Local\Temp\___channel_close_test_go.exe -test.v -test.run ^\QTestCloseChanner\E$ #gosetup
=== RUN   TestCloseChanner
0
1
2
3
4
5
6
7
8
9
0
--- PASS: TestCloseChanner (0.00s)
PASS
Process finished with exit code 0
相关文章
|
4月前
|
存储 安全 Java
Go 基础数据结构的底层原理(slice,channel,map)
Go 基础数据结构的底层原理(slice,channel,map)
53 0
|
1月前
|
设计模式 缓存 安全
一篇文章带你吃透Go语言的Atomic和Channel--实战方法
一篇文章带你吃透Go语言的Atomic和Channel--实战方法
29 0
|
1月前
|
存储 Go
|
3月前
|
Go
Go语言Channel进阶:巧妙运用超时机制
Go语言Channel进阶:巧妙运用超时机制
75 0
|
3月前
|
安全 Go 调度
Go语言的并发编程:goroutine和channel详解
Go语言的并发编程:goroutine和channel详解
87 2
|
4月前
|
存储 缓存 安全
Go Channel详解
Go Channel详解
71 0
|
4月前
|
Go
一图胜千言,帮你搞懂Go面试中常问的channel问题!
一图胜千言,帮你搞懂Go面试中常问的channel问题!
|
4月前
|
测试技术 Go
go channel 用例
go channel 用例
25 0
|
4月前
|
Cloud Native 安全 测试技术
GO 语言处理并发的时候我们是选择sync还是channel
GO 语言处理并发的时候我们是选择sync还是channel
|
11月前
|
存储 缓存 安全
面试某大厂,被Go的Channel给吊打了,这次一次性通关channel。
面试某大厂,被Go的Channel给吊打了,这次一次性通关channel。
637 0