管道(channel)的关闭

【1】管道的关闭:
使用内置函数close可以关闭管道,当管道关闭后,就不能再向管道写入数据了,但是仍然可以从该管道读取数据。(类似商城排队限流,一旦进去10个人后,保安拉取一个警戒线,不准外面的人在进入了,但是里面进去的10个人,仍然可以进行操作)

package main

import "fmt"

func main() {
	//定义一个int类型的管道
	var intChan chan int
	//通过make初始化:管道可以存放3个int类型的数据
	intChan = make(chan int, 3)
	//向管道存放数据,箭头指向管道:
	intChan <- 10
	intChan <- 20

	//关闭管道
	close(intChan)

	//再次写入数据:-----报错:send on closed channel
	//intChan <- 30

	//当管道关闭后,读取数据是可以的:
	num := <-intChan
	fmt.Println(num)
}

管道的遍历
管道支持for-range的方式进行遍历,请注意两个细节
1、在遍历时,如果管道没有关闭,则会出现deadlock的错误
2、在遍历时,如果管道已经关闭,则会正常遍历数据,遍历完后,就会退出遍历

package main

import "fmt"

func main() {
	//定义一个int类型的管道
	var intChan chan int
	//通过make初始化:管道可以存放100个int类型的数据
	intChan = make(chan int, 100)
	for i := 0; i < 100; i++ {
		intChan <- i
	}

	//在遍历前,如果没有关闭管道,就会出现deadlock的错误,所以在遍历前,需要进行关闭管道
	//关闭管道
	close(intChan)
	//遍历
	for v := range intChan {
		fmt.Println("value= ", v)
	}

}

### Go语言Channel使用教程 #### 创建通道 在Go语言中,`make()` 函数用来创建一个新的通道。可以指定容量来定义带缓冲的通道。 ```go ch := make(chan int) // 创建不带缓冲的int类型的通道 bufferedCh := make(chan int, 5) // 创建带缓冲区大小为5的int类型通道 ``` [^1] #### 发送和接收数据 通过 `<-` 运算符实现向通道发送或从通道接收数据: ```go // 向通道发送数据 ch <- value // 接收来自通道的数据并赋给变量result result := <- ch ``` 对于无缓冲的通道而言,在一个goroutine里执行 `ch <- data` 将会阻塞直到另一个goroutine准备好了要读取该值;同样地,当尝试从中读取时也会被挂起直至有可用的信息为止[^5]。 #### 关闭通道 只有生产者应该负责关闭通道,并且一旦关闭之后就不能再往里面放入任何新的项目了。试图在一个已经结束后的管道内放置更多条目将会引发panic错误。 ```go close(ch) ``` 如果接收到的是零值,则可以通过第二个返回参数判断是否是因为遍历完毕而自然终止还是因为其他原因提前退出循环: ```go if val, ok := <-ch; !ok { fmt.Println("channel closed") } ``` [^4] #### 带缓冲与非缓冲的区别 - **无缓冲**: 当前这个协程A往通道中放数据,必须等到别的协程B去取数据了,A才能继续放下一条消息; - **有缓冲**: 如果还有空间的话可以直接放进队列当中而不必等待消费者端响应。不过需要注意的是,即使是有缓存的情况也存在一定的同步机制——比如当所有的槽位都被占用了以后再次写入就会变成阻塞性质的行为,反之亦然。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值