首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用context.Err()防止竞争条件

使用context.Err()防止竞争条件
EN

Stack Overflow用户
提问于 2021-04-06 06:12:43
回答 1查看 103关注 0票数 1

据我所知,在Go中使用上下文时,检查上下文是否被取消或达到最后期限的正确方法是在相关代码之后调用context.Err()。所以就像这样:

代码语言:javascript
复制
func myFunc(ctx context.Context) {
    // call some context-aware functionality
    result, err := SomeContextAwareFunc(ctx)

    // check if we hit a deadline or cancellation
    if ctxErr := ctx.Err(); ctxErr != nil {
        // handle an expired and/or cancelled context here
    }

    // process the result
    _ = result
}

不过,如果我没记错的话,这代表了一个竞态条件。上下文可能在SomeContextAwareFunc之后但在调用Err函数之前过期。在这种情况下,我们会认为上下文过期会缩短SomeContextAwareFunc,但实际上并非如此(例如,我们可以使用结果)。

我在操场上用函数返回和调用错误之间的人为延迟测试了这一点,它确实错误地指示了过期的上下文。https://play.golang.org/p/Rd-fhWOW-AB

预防这种情况的正确方法是什么?上下文感知函数是否必须总是返回错误,以便调用者只在返回错误时才检查上下文?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-04-06 06:38:14

如果SomeContextFunction返回上下文错误或wraps上下文错误,则使用以下代码确定SomeContextFunction是由于截止时间还是由于取消而返回的:

代码语言:javascript
复制
result, err := SomeContextAwareFunc(ctx)
if errors.Is(err, context.DeadlineExceeded) || errors.Is(err, context.Canceled) {
     // deadline exceeded or canceled
} else if err != nil {
     // some other eror
}

由于SomeContextAwareFunc返回后可能会过期或取消上下文,因此测试从SomeContextAwareFunc返回的错误是确定函数失败原因的唯一方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66960426

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档