• 【Golang】高性能编程之超时退出协程


    超时控制在网络编程中是非常常见的,利用 context.WithTimeout和time.After都能够很轻易地实现。
    func doBadthing(done chan bool) {
    time.Sleep(time.Second)
    done <- true
    }

    func timeout(f func(chan bool)) error {
    done := make(chan bool)
    go f(done)
    select {
    case <-done:
    fmt.Println("done")
    return nil
    case <-time.After(time.Millisecond):
    return fmt.Errorf("timeout")
    }
    }

    // timeout(doBadthing)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    对于这段代码,会出现超时,子协程是不能够全部正常退出的。参见如何退出协程 goroutine 超时场景

    它的问题是,它使用的是无缓冲的channel,当select执行到超时,doBadthing发送给done的信息没有接收方,因为进到了超时分支,所以,发送方doBadthing会一直阻塞,导致协程不能退出。
    那如果在实际的业务中,我们使用了上述的代码,那越来越多的协程会残留在程序中,最终会导致内存耗尽(每个协程约占 2K 空间),程序崩溃。
    如何避免呢?
    1.创建有缓冲区的channel,使得即使没有接收方,发送方也不会发生阻塞。
    2.使用select尝试发送
    func doGoodthing(done chan bool) {
    time.Sleep(time.Second)
    select {
    case done <- true:
    default:
    return
    }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    如果发送失败则,会直接退出。
    3.拆分任务,分为多段,配合select使用,判断哪一段超时。

    强制Kill goroutine
    goroutine 只能自己退出,而不能被其他 goroutine 强制关闭或杀死。
    goroutine 被设计为不可以从外部无条件地结束掉,只能通过 channel 来与它通信。也就是说,每一个 goroutine 都需要承担自己退出的责任。(A goroutine cannot be programmatically killed. It can only commit a cooperative suicide.)
    建议
    因为 goroutine 不能被强制 kill,在超时或其他类似的场景下,为了 goroutine 尽可能正常退出,建议如下:
    1.尽量使用非阻塞 I/O(非阻塞 I/O 常用来实现高性能的网络库),阻塞 I/O 很可能导致 goroutine 在某个调用一直等待,而无法正确结束。
    2.业务逻辑总是考虑退出机制,避免死循环。
    3.任务分段执行,超时后即时退出,避免 goroutine 无用的执行过多,浪费资源。
    参考
    如何退出协程 goroutine 超时场景
    ————————————————
    版权声明:本文为CSDN博主「Kaimar」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/weixin_40910614/article/details/121927730

  • 相关阅读:
    内容页超连接关键词的完美实现
    鼠标经过文字链接时出现漂亮的提示层
    简单的jQuery检测注册用户名
    触发Repeater中的Dropdownlist的SelectedIndexChanged如何获得Repeater的当前行
    读取XML的节点属性并绑定到ListBox
    第十八章 6string型字符串的替换 简单
    第十八章 2string字符串 简单
    第十七章 特殊成员_函数指针也可以做为参数 简单
    第十七章 特殊成员_类的函数指针 简单
    第十七章 特殊成员_成员函数指针数组 简单
  • 原文地址:https://www.cnblogs.com/ExMan/p/16779136.html
Copyright © 2020-2023  润新知