利用select为读channel设置超时

使用<- chanfor range循环从通道中读取数据都是会阻塞。

有时,您想为从某个通道读取数据设定时间限制。

这就需要使用select了:

import (
	"fmt"
	"time"
)

func main() {
	chResult := make(chan int, 1)

	go func() {
		time.Sleep(1 * time.Second)
		chResult <- 5
		fmt.Printf("Worker finished")
	}()

	select {
	case res := <-chResult:
		fmt.Printf("Got %d from worker\n", res)
	case <-time.After(100 * time.Millisecond):
		fmt.Printf("Timed out before worker finished\n")
	}
}

----------Output----------
Timed out before worker finished

我们来深入了解一下这是如何工作的:

select {
	case res := <-chResult:
		fmt.Printf("Got %d from worker\n", res)
	case <-time.After(100 * time.Millisecond):
		fmt.Printf("Timed out before worker finished\n")
}
  • time.After 返回的是一个时间类型的channel,在给定时间之后(上例是100毫秒),将会有值被放入通道。我们称其为超时通道。

  • 我们并不关心会从超时通道读取到什么值。我们仅关心是否有值被发送到该通道。

  • 我们使用select在2个通道上等待:一个是chResult,另一个是超时通道。

  • select将在从任意一个通道获取到值时就结束。

  • 我们要么在超时之前从chResult获取到值,要么过期之后从超时通道获取到值。

最后更新于