Golang的通道技巧

  • time.After(d) 函数声明为 func After(d Duration) <-chan Time ,在 Duration d 之后,当前时间被发到返回的通道;因此它和 NewTimer(d).C 等价;它类似 Tick() ,但 After() 只发送一次时间。可以使用此函数应对简单的超时模式,以下为三种形式。

    • 要执行某个任务(如从通道 ch 中读取数据),但最多等待1秒。先创建一个信号通道,之后启动一个 lambda 协程,协程在给通道发送数据前休眠:
    • time.After() 函数替换 timeout-channel 。可以在 select 中使用来让发送信号超时或停止协程的执行。以下代码,在 timeoutNs 纳秒后执行 selecttimeout 分支后,包含 client.Calllambda 协程也随之结束,不会给通道 ch 返回值。缓冲大小设置为 1 是必要的,可以避免协程死锁以及确保超时的通道可以被垃圾回收。需要注意如果 select 中的某些非定时器选项的通道读写密集,则可能无法结束这些进程。这种情况如果将 select 放到一个 for 循环中,也无法精确地在定时器通道写入时就结束,因为 select 对可以执行的多个 case 采取伪随机算法选择,可能结束进程的时间要比定时器发出信号略晚一些。
    • 假设程序从多个复制的数据库同时读取,只需要接收首先到达的答案, Query 函数获取数据库的连接切片,并行请求每一个数据库并返回收到的第一个响应。结果通道 ch 必须是带缓冲的,以保证第一个发送进来的数据有地方可以存放,确保放入的首个数据总会成功: