Go 中 case 选择的优先级
Go 的 select 语句中,case 求值的顺序是不确定的,导致处理上下文时可能存在不一致的情况及时取消活动。一种常见的场景涉及发送定期心跳的后台例程,当上下文被取消时,该例程应立即停止。然而,由于不可预测的选择顺序,即使在上下文取消后也可以观察到心跳的发送。
为了确保在上下文取消时立即终止心跳,需要更强大的方法。首选方法是明确优先考虑上下文取消情况,而不是依赖情况评估的顺序。这可以通过使用具有所需优先级的嵌套 select 语句来实现:上下文取消情况应放置在外部 select 语句中,然后是处理心跳功能的第二个 select 语句。
考虑以下修改后的代码:
func sendRegularHeartbeats(ctx context.Context) { ticker := time.NewTicker(time.Second) defer ticker.Stop() for { //outer select, giving priority to context cancellation select { case <-ctx.Done(): return default: } //inner select for heartbeat functionality select { case <-ctx.Done(): return case <-ticker.C: sendHeartbeat() } } }
通过将心跳处理情况嵌套在外部 select 语句中,我们有效地优先考虑上下文取消情况,确保在上下文被取消时立即执行。这消除了上下文取消后发送任何心跳的可能性,保证了所需的行为。
以上是如何保证Go的select语句及时取消上下文?的详细内容。更多信息请关注PHP中文网其他相关文章!