go语言的基础知识4.3

本文探讨了Go语言中无缓冲通道的阻塞机制,重点介绍了如何通过select关键字实现通道的超时控制,包括使用time.After来设置接收或发送操作的超时。实例演示了如何在并发编程中优雅处理channel的满或空问题,避免进程阻塞。
摘要由CSDN通过智能技术生成

1.关于Go语言的有缓冲通道和无缓冲通道
2.关于go语言无缓冲通道的阻塞行为
3.使用select实现channel的超时处理,使用time.After实现select的超时控制
PS: 学习自 https://haicoder.net/golang/golang-channel-select.html

//-- chan有只读channel和只写channel

//-- 无缓冲的通道:
//无缓冲的通道是指在接收前没有能力保存任何值的通道。这种类型的通道要求发送 goroutine 和接收 goroutine 同时准备好,才能完成发送和接收操作。
//如果两个 goroutine 没有同时准备好,通道会导致先执行发送或接收操作的 goroutine 阻塞等待。
// 创建无缓冲 channel
// c1 := make(chan int)

//-- 带缓冲的通道
// 带缓冲的通道是一种在被接收前能存储一个或者多个值的通道。这种类型的通道并不强制要求 goroutine 之间必须同时完成发送和接收。
// 创建带缓冲 channel
// c := make(chan int, 3)

//-- 使用 select 实现 channel 超时处理
//-- 在并发编程的通信过程中,经常会遇到超时问题,
//即向 channel 写数据时发现 channel 已满,或者从 channel 试图读取数据时发现 channel 为空。
//如果不正确处理这些情况,很可能会导致整个 goroutine 锁死。Go 语言 channel 超时场景:
//-- name := <-chanName
//我们从管道 chanName 里面接受数据,并将接受到的数据存放到变量 name 中,如果我们的程序一直没有给管道 chanName 发送数据,那么上面的代码就会永久的阻塞。
//那么,此时,如果没有合理的超时处理机制,这行代码很可能会导致整个进程阻塞。
func chanTest() {
	ch := make(chan int)
	quite := make(chan bool)
	//-- 新开一个协程
	go func() {
		for {
			//-- select 有比较多的限制,其中最重要的一条限制就是每个 case 语句里必须是一个 IO 操作。
			//-- 并且,select 后面并不带判断条件,而是直接去查看 case 语句。
			//-- 每个 case 语句都必须是一个面向 channel 的操作。当 select 里面有多个 case 都满足条件出发时,则 select 会随机选取一个 case 执行。
			//-- select 关键字,可以同时响应多个通道的操作
			select {
			case num := <-ch:
				//-- 如果ch里面有数据,则会往下走,如果没有数据正常会阻塞
				fmt.Println("recv num = ", num)

			case <-time.After(2 * time.Second):
				//-- 上面的ch如果一直没数据会阻塞,那么select也会检测其他case条件
				//-- 检测到后3秒超时后继续往下走
				fmt.Println("TmeOut")
				//-- 向管道写入数据
				quite <- true
			case <-time.After(5 * time.Second):
				//-- 可以使用 time.After 来实现 select 的超时控制,同时,我们还可以使用 break 语句,来结束 select 语句。
				fmt.Println("超时,退出循环")
				quite <- true
				break
			}
		}
	}()

	for i := 0; i < 1; i++ {
		ch <- i
		time.Sleep(time.Second)
	}
	//-- 这里暂时阻塞,直到可读
	<-quite
	fmt.Println("Process Done!")
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值