一招教你无阻塞读写Golang channel

本文介绍了Golang中channel可能导致阻塞的场景,并提供了解决方案。通过使用select和结合超时设置,实现了无阻塞的读写操作,避免了死锁问题。文章还给出了具体的示例代码,帮助理解如何在实际应用中避免channel阻塞。
摘要由CSDN通过智能技术生成

无论是无缓冲通道,还是有缓冲通道,都存在阻塞的情况,教你一招再也不遇到channel阻塞的问题。

这篇文章会介绍,哪些情况会存在阻塞,以及如何使用select解决阻塞。

阻塞场景

阻塞场景共4个,有缓存和无缓冲各2个。

无缓冲通道的特点是,发送的数据需要被读取后,发送才会完成,它阻塞场景:

  1. 通道中无数据,但执行读通道。
  2. 通道中无数据,向通道写数据,但无协程读取。
// 场景1
func ReadNoDataFromNoBufCh() {
   
	noBufCh := make(chan int)

	<-noBufCh
	fmt.Println("read from no buffer channel success")

	// Output:
	// fatal error: all goroutines are asleep - deadlock!
}

// 场景2
func WriteNoBufCh() {
   
	ch := make(chan int)

	ch <- 1
	fmt.Println("write success no block")
	
	// Output:
	// fatal error: all goroutines are asleep - deadlock!
}

注:示例代码中的Output注释代表函数的执行结果,每一个函数都由于阻塞在通道操作而无法继续向下执行,最后报了死锁错误。

有缓存通道的特点是,有缓存时可以向通道中写入数据后直接返回,缓存中有数据时可以从通道中读到数据直接返回,这时有缓存通道是不会阻塞的,它阻塞的场景是:

  1. 通道的缓存无数据,但执行读通道。
  2. 通道的缓存已经占满,向通道写数据,但无协程读。
// 场景1
func ReadNoDataFromBufCh() {
   
	bufCh := make(chan int, 1)

	<-bufCh
	fmt.Println("read from no buffer channel success")

	// Output:
	// fatal error: all goroutines are asleep - deadlock!
}

// 场景2
func 
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值