Go从入门到精通——关闭通道后继续使用通道

关闭通道后继续使用通道

  通道是一个引用对象,和 map 类似。map 在没有任何外部引用时 ,Go 程序在运行(runtime)会自动对内存进行垃圾回收(Garbage Collection,GC)。类似的,通道也可以被垃圾回收,但是通道也可以被主动关闭的。

1、格式

  使用 close() 来关闭一个通道:

close(ch)

  关闭的通道依然可以被访问,访问被关闭的通道将会发生一些问题。

 2、给关闭通道发送数据将会触发 panic

  被关闭的通道不会被置为 nil。如果尝试对已经关闭的通道进行发送,将会触发宕机。

package main

import "fmt"

func main() {
	//创建一个整型的通道
	ch := make(chan int)

	//关闭通道
	close(ch)

	//打印通道的指针,容量和长度
	fmt.Println("ptr:%p  cap:%d len:%d\n", ch, cap(ch), len(ch))

	//给关闭的通道发送数据
	ch <- 1
}

  代码执行后报错:

DAP server listening at: 127.0.0.1:54164
Type 'dlv help' for list of commands.
ptr:%p  cap:%d len:%d
 0xc000086060 0 0
panic: send on closed channel

goroutine 1 [running]:
main.main()
	d:/go-testfiles/并发-给关闭通道发送数据将会触发panic.go:16 +0x197
Process 13984 has exited with status 2
Detaching
dlv dap (10796) exited with code: 0

3、从已关闭的通道接收数据时将不会发生阻塞

  从已关闭的通道接收数据或者正在接收数据时,将会接收到通道类型的零值,然后停止阻塞并返回。

package main

import (
	"fmt"
)

func main() {
	//创建一个整型带两个缓冲的通道
	ch := make(chan int, 2)

	//给通道放入两个数据
	ch <- 0
	ch <- 1

	//关闭缓冲
	close(ch)

	//遍历缓冲所有数据,且多遍历1个
	for i := 0; i < cap(ch)+1; i++ {
		//从通道中取出数据
		v, ok := <-ch
		//打印取出数据的状态
		fmt.Println(v, ok)
	}
}

  代码输出如下:

Starting: D:\go-testfiles\bin\dlv.exe dap --check-go-version=false --listen=127.0.0.1:55388 from d:\go-testfiles
DAP server listening at: 127.0.0.1:55388
Type 'dlv help' for list of commands.
0 true
1 true
0 false              //表示通道在关闭状态下取出的值,0 表示这个通道的默认值,false表示没有获取成功,因为此通道已经空了。
Process 15932 has exited with status 0
Detaching
dlv dap (16360) exited with code: 0
posted @ 2022-05-11 14:11  左扬  阅读(231)  评论(0编辑  收藏  举报
levels of contents