解决 Go select 语句中的优先级
在 Go 中使用 select 语句时,case 评估的顺序通常是不确定的。然而,在某些场景下,我们可能需要优先执行某些情况。
上下文取消优先
考虑下面的代码,我们希望在其中优雅地关闭上下文取消时的心跳发送者:
func sendRegularHeartbeats(ctx context.Context) { for { select { case <-ctx.Done(): return case <-time.After(1 * time.Second): sendHeartbeat() } } }
但是,当上下文立即关闭时,代码在执行“完成”案例之前仍可能传输心跳。
解决方案:辅助通道的优先级
解决此问题的一种方法是使用辅助通道优先考虑上下文取消情况:
func sendRegularHeartbeats(ctx context.Context) { done := make(chan struct{}) go func() { <-ctx.Done() close(done) }() for { select { case <-done: return case <-time.After(1 * time.Second): sendHeartbeat() } } }
在这种情况下,done 通道确保当上下文被取消时,首先评估“ctx.Done()”情况。
其他注意事项
虽然此解决方案提高了优先级,但并没有完全消除这种可能性在执行“完成”案例之前发送的心跳。对于真正同步的关闭,请考虑使用原子变量或互斥体等同步原语,以确保在上下文取消时立即终止心跳传输。
以上是如何对 Go 的 select 语句中的情况进行优先级排序以实现确定性执行?的详细内容。更多信息请关注PHP中文网其他相关文章!