首页 >后端开发 >Golang >如何保证 Go 的 select 语句中上下文取消的优先级?

如何保证 Go 的 select 语句中上下文取消的优先级?

DDD
DDD原创
2024-12-20 02:09:13365浏览

How Can We Guarantee Context Cancellation Priority in Go's `select` Statement?

优先考虑 Go select 语句

问题:

在 Go select 语句中,顺序案例块的评估是不确定的。这可能会导致即使相应的通道已准备好接收,也无法立即输入特定 case 块的情况。

场景:

考虑 sendRegularHeartbeats()定期发送心跳消息并在其上下文被取消时终止的函数。如果在发送第一个心跳消息之前取消上下文,我们预计不会传输任何心跳消息。

非确定性评估问题:

在某些情况下,尽管在函数启动之前上下文已取消,但仍会发送心跳消息。这是因为评估的顺序是不可预测的,并且默认情况或心跳情况可能会在上下文情况之前输入。

不正确的建议:

一个建议的解决方案是添加“isContextclose”-检查心跳情况。然而,这不是一个可靠的解决方案,因为上下文和心跳通道都可以同时准备好读取。

建议的解决方案:原始选择

优先考虑上下文情况,我们可以引入一个原始的 select 语句来测试上下文通道是否准备就绪。只有当上下文通道没有准备好时,才会执行第二个 select 语句。

func sendRegularHeartbeats(ctx context.Context) {
    for {
        // Primordial select: Check for context channel being ready only.
        select {
        case <-ctx.Done():
            return
        default:
        }

        // Secondary select: Handle heartbeat logic.
        select {
        case <-ctx.Done():
            return
        case <-time.After(1 * time.Second):
            sendHeartbeat()
        }
    }
}

不完美:

虽然这种方法有效地优先考虑了上下文情况,但它可能仍然允许“足够接近”的事件。例如,如果在上下文通道准备好之后不久心跳事件到达,则可以在进入上下文情况之前发送心跳。目前的Go语言实现还没有完美的解决这个问题。

以上是如何保证 Go 的 select 语句中上下文取消的优先级?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn