背景:我正在利用自定义 LDAP 服务器包。它使用Done请求中的通道让处理程序知道是否(例如客户端断开连接),因此处理程序也应该中止。由于Done通道是处理取消的旧方法 - 并且我希望支持取消链接 - 我context.Context从这个通道创建了一个,如下所示:func doneContext(p context.Context, done <-chan bool) ( ctx context.Context, cancel context.CancelFunc,) { ctx, cancel = context.WithCancel(p) go func() { <-done cancel() // done closed, so cancel our context }() return}这假设done通道将关闭:客户端断开连接;和成功的处理程序(完全运行完成)第一个事实证明是正确的,而第二个事实则不然。成功的处理程序调用不会触发通道done关闭 - 因此我泄漏了 go-routines。为了解决这个问题 - 由于我context.Context在处理程序完成时取消了自己的操作 - 成功与否,例如// convert the client request's Done channel into a context.Contextctx, cancel := doneContext(context.Background(), m.Done)defer cancel() // clean-up context: rain or shine我doneContext像这样更新了 go 例程:go func() { select { case <-done: cancel() // done closed, so cancel our context (like before) case <-ctx.Done(): // when our context is canceled, recover the go-routine (even if done never closes) }}()问题:这是将旧式done频道升级为更现代频道的正确方法吗context.Context我应该担心我正在使用的外部包没有关闭通道吗done?即会GC收集该通道,即使它从未关闭?
- 1 回答
- 0 关注
- 86 浏览
添加回答
举报
0/150
提交
取消