具有通道就绪性的异步通信
在Go中,通道促进了goroutine之间的并发通信。当处理缓冲发送通道和无缓冲接收通道时,可以同时选择两个通道以优化通信流。本文探讨了在最小化 CPU 利用率的同时实现此功能的方法。
要理解该问题,请考虑以下上下文:
<code class="go">s := make(chan<- int, 5) // Buffered send channel r := make(<-chan int) // Unbuffered receive channel</code>
问题是是否可以同时选择两者通道,当数据可供读取时,r 被选中,当通道未满时,s 被选中。
解决方案
可以使用 select 来实现这一点带有默认情况的语句。由于使用 select 时仅评估一次要发送的值,因此如果两个通道都未准备好,则该值将变得过时。为了避免这种情况,在选择语句中添加了默认情况,如果两个通道都没有准备好,则执行该默认情况。在这种默认情况下,程序会短暂休眠,让通道准备就绪,然后使用更新的值重试。
<code class="go">s := make(chan<- int, 5) r := make(<-chan int) for { v := valueToSend() // Evaluated each time we try to send select { case s <- v: fmt.Println("Sent value:", v) case vr := <-r: fmt.Println("Received:", vr) default: // If none are ready currently, we end up here time.Sleep(time.Millisecond * 1) } }</code>
警告
不建议使用 len(r) 或 cap(s) 检查通道准备情况,然后发送/接收,因为通道可能会在检查和尝试发送/接收之间改变其状态。
以上是如何在 Go 中实现通道就绪的异步通信,同时最小化 CPU 利用率?的详细内容。更多信息请关注PHP中文网其他相关文章!