go - 从go例程外部停止goroutine

标签 go memory-leaks goroutine

我这里有一个go例程,需要在上下文到期时从外部go例程中停止该例程。但是,当上下文过期时,go例程不会停止,并且即使控制它的go例程停止也继续进行。

package main

import (
    "context"
    "fmt"
    "time"
)

func main() {
    ctxParent := context.Background()

    ch := make(chan bool)

    d := 5 * time.Second

    ctx, cancel := context.WithTimeout(ctxParent, d)
    defer cancel()
    go doSomething(ctx, ch)

    // go func() {
    select {

    // done
    case _ = <-ch:
        fmt.Println("goroutine finished")
    }

    fmt.Println("waiting 11 seconds on main thread, ending all go routines")

    time.Sleep(11 * time.Second)

    fmt.Println(">>>> END")
}

func doSomething(ctx context.Context, ch chan<- bool) {

    // how to kill this go routine if context expires??
    go func(ctx context.Context) {
        fmt.Println("LOTS OF WORK TIME..")
        for i := 0; i < 1000; i++ {
            time.Sleep(1 * time.Second) // LOTS OF WORK
            fmt.Println(i)
        }

    }(ctx)

    select {
    case _ = <-ctx.Done():
        fmt.Println("*** Go routine timed out in 5 seconds!!! ****")
        ch <- true
        return

    }
}

这将打印(https://play.golang.org/p/L8u51odiHxS)
LOTS OF WORK TIME..
0
1
2
3
4
*** Go routine timed out in 5 seconds!!! ****
goroutine finished
waiting 11 seconds on main thread, ending all go routines
5
6
7
8
9
10
11
12
13
14
15
>>>> END
它不应该打印5,6,7,8 ...等。是否有办法杀死此内部go例程?

最佳答案

您必须在goroutine中检查上下文过期/取消:

 go func(ctx context.Context) {
        fmt.Println("LOTS OF WORK TIME..")
        for i := 0; i < 1000; i++ {
            select {
              case <-ctx.Done():
                  return
              default:
            }
            time.Sleep(1 * time.Second) // LOTS OF WORK
            fmt.Println(i)
        }

    }(ctx)

关于go - 从go例程外部停止goroutine,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63713310/

相关文章:

go - 几乎重复自己

go - 如何在 Go 中打印 float 的二进制表示?

ios - iOS 中的核心数据内存占用不断增长

c - 我的(自定义)程序如何泄漏内存?我正在为 pset5 做准备

go - 对goroutines中的延迟感到困惑

string - 可以在Go中使用`string()`将字节转换为空字符串吗?

.net - .Net 3.5 中的 XML 序列化是否仍然存在已知的内存泄漏?

go - 为什么 make([]int, 14) 中有 runtime.morestack 而 make([]int, 13) 中没有?

concurrency - 不同输入数据的 Goroutine 执行时间

go - 如何将FaunaDB的时间类型数据映射到go lang变量?