go - 从完成 channel 和未关闭 channel 的 GC 生成 context.Context

标签 go garbage-collection cancellation

背景:

我正在利用自定义 LDAP 服务器 package .它使用 Done请求中的 channel 让处理程序知道 - 比如说客户端断开连接 - 因此处理程序也应该中止。 For example .

由于 Done channel 是处理取消的旧方式 - 我希望支持取消链接 - 我创建了一个 context.Context从这个 channel 像这样:

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 channel 将被关闭:
  • 客户端断开连接;
  • 成功的处理程序(完全运行到完成)

  • 第一个证明是正确的 - 第二个没有。成功的处理程序调用将 不是 触发done channel 要关闭 - 因此我正在泄漏 go-routines。

    为了解决这个问题 - 因为我取消了自己的 context.Context在处理程序完成时 - 成功与否,例如
    // convert the client request's Done channel into a context.Context
    ctx, cancel := doneContext(context.Background(), m.Done)
    defer cancel() // clean-up context: rain or shine
    

    我更新了doneContext像这样去例行公事:
    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 channel ?
  • 即将GC收集这个 channel ,即使它永远不会关闭?
  • 最佳答案

    您无需关闭 channel 。如果没有任何东西引用 channel ,它将被垃圾收集。

    您的 channel 逻辑显示正确。

    关于go - 从完成 channel 和未关闭 channel 的 GC 生成 context.Context,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58223267/

    相关文章:

    c# - 如何取消可观察序列

    dictionary - 在自定义类型中使用迭代器属性

    go - 为什么函数 runtime_args 可以这样表达?

    Golang 堆栈跟踪详细信息

    git - 如何使用 dep 管理的开发 vendor 包?

    java - 嵌套循环在 android 中导致大量垃圾收集?

    java - 如何添加安全防护来释放本应由客户端代码显式释放的资源

    c - 为什么 GC 中的白色/灰色/黑色?

    javascript - 取消链接中 onClick 触发的 javascript 函数

    reactjs - 在 ReactJS 中卸载组件时取消 promise