使用contexts来避免goroutines泄露
来源:互联网 发布:公共基础知识考试软件 编辑:程序博客网 时间:2024/05/02 00:14
使用contexts来避免goroutines泄露
context包通过context
的Done
通道(channel)使得管理在同一个调用路径下的链条式调用变成了可能。
在本文中,将审查怎么使用context
包来避免goroutines的泄露。
假定有一个启用一个内部goroutine的函数。一旦调用此函数,调用者就可能无法终止这个函数启动的goroutine。
// gen is a broken generator that will leak a goroutine.func gen() <-chan int { ch := make(chan int) go func() { var n int for { ch <- n n++ } }() return ch}
上面的生成器启动一个无限循环的goroutine,但调用者将在值达到5时销毁掉。
// The call site of gen doesn't have a for n := range gen() { fmt.Println(n) if n == 5 { break }}
一旦调用者调用了这个生成器,goroutine将执行无限循环永远地执行下去。代码中将会泄露一个goroutine。
可以通过向一个停止通道中发送信号至内部goroutine来避免这个问题,但是这里有一个更好的解决方案:可取消的contexts。生成器通过select监听context的Done通道,一旦context的完成,内部goroutine将被取消。
// gen is a generator that can be cancellable by cancelling the ctx.func gen(ctx context.Context) <-chan int { ch := make(chan int) go func() { var n int for { select { case <-ctx.Done(): return // avoid leaking of this goroutine when ctx is done. case ch <- n: n++ } } }() return ch}
现在调用者在完成任务进行销毁时可以发生信号至生成器。一旦取消函数被调用,内部goroutine将被返回。
ctx, cancel := context.WithCancel(context.Background())defer cancel() // make sure all paths cancel the context to avoid context leakfor n := range gen(ctx) { fmt.Println(n) if n == 5 { cancel() break }}// ...
完整的示例代码如下:
package mainimport ( "context" "fmt")func gen(ctx context.Context) <-chan int { ch := make(chan int) go func() { var n int for { select { case <-ctx.Done(): return case ch <- n: n++ } } }() return ch}func main() { ctx, cancel := context.WithCancel(context.Background()) defer cancel() for n := range gen(ctx) { fmt.Println(n) if n == 5 { cancel() break } }}
1 0
- 使用contexts来避免goroutines泄露
- 如何使用弱引用来避免内存泄露
- 用try finally来避免内存泄露。
- 使用goto语句避免内存泄露
- 使用Process Explorer来查看句柄泄露
- 使用Instruments来检测内存泄露
- 如何避免使用CreateThread函数导致的内存泄露
- 如何避免使用CreateThread函数导致的内存泄露
- Android避免内存泄露:合理使用getContext()和getApplication()
- Android避免内存泄露:合理使用getContext()和getApplication()
- Android避免内存泄露:合理使用getContext()和getApplication()
- JNI使用注意与避免内存泄露总结
- Android避免内存泄露:合理使用getContext()和getApplication()
- Android避免内存泄露:合理使用getContext()和getApplication()
- 使用同步对象避免多线程退出时内存泄露
- Android避免内存泄露:合理使用getContext()和getApplication()
- 避免使用不当pthread_create函数造成内存泄露
- Linux下正确使用getifaddrs()函数避免内存泄露
- 分享一款Web压力测试工具Pylot
- php 获取本周星期一到天的各自时间戳(从早上零点到晚上23:59)
- 用.msi安装node时安装失败,出现rolling back action
- maven 打可执行jar
- 真实项目运用-RecyclerView封装
- 使用contexts来避免goroutines泄露
- 解决ios设备自带邮箱只能接收邮件不能发送邮件问题的方法
- MySQL show命令
- kettle调试远程执行的作业
- Mycat范围求模分片
- 理解OAuth 2.0
- Facebook App 优化工具 ReDex
- Truth:一个流畅的断言框架
- (前端预热)初识grunt NODE→grunt