【Go】04-context
Context 是什么?
- Context 是 Go 中用来传递上下文信息的一种方式,要用来在 goroutine 之间传递上下文信息,包括:取消信号、超时时间、截止时间、k-v 等
- 常见场景:当作为 server 处理 client 信息时,client 异常关闭之后,server 应该同步终止 client 之前的请求资源,即
gracefully terminate(这样server能够节省资源,不处理 client 多余的请求,毕竟 client 已经异常关闭)
Context 如何使用?
基础用法
1 | package main |
- 通过调用
context包来创建一个 context,用来传递信息 - 也可以使用
ctx := context.Background(),两者的差异可见[context.TODO() or context.Background(), which one should I prefer?。两者本质一致,差异在于使用TODO用来表示不确定性,后续要变更。Background()则更为明确
传递变量
1 | package main |
通过
context可以用来传递参数,此时可在调用链中继续使用,注意使用场景,简而言之,就是不要滥用,下面给出了一个注意点Contexts can be a powerful tool with all the values they can hold, but a balance needs to be struck between data being stored in a context and data being passed to a function as parameters. It may seem tempting to put all of your data in a context and use that data in your functions instead of parameters, but that can lead to code that is hard to read and maintain. A good rule of thumb is that any data required for a function to run should be passed as parameters. Sometimes, for example, it can be useful to keep values such as usernames in context values for use when logging information for later. However, if the username is used to determine if a function should display some specific information, you’d want to include it as a function parameter even if it’s already available from the context. This way when you, or someone else, looks at the function in the future, it’s easier to see which data is actually being used.
context 传递变量时,同一个函数中,值不会被改变
通过 语义 终止运行/同步信号(context.WithCancel)
1 | package main |
- 通过向 channel 传递消息,来决定是否终止后续运行。逐步传递,保证上层 Goroutine 执行出现错误时,将信号及时同步给下层
ctx.Done()被执行,说明已到达设定的终止语义
通过 终止时间 终止运行
context.WithDeadline
1 | ... |
通过指定超时时间,来决定是否终止后续运行。如果超时,则会自动终止调用
同时使用
defer cancelCtx()和cancelCtx()原因: 后者是主动调用,没有回收一些资源(因为写的是 break),前者是更加安全的方式The
defer cancelCtx()isn’t necessarily required because the other call will always be run, but it can be useful to keep it in case there are anyreturnstatements in the future that cause it to be missed. When a context is canceled from a deadline, the cancel function is still required to be called in order to clean up any resources that were used, so this is more of a safety measure.
context.WithTimeout
1 | ... |
- 简化使用




