从 goroutine 之外停止 goroutine

use*_*932 -1 memory-leaks go 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

    }
}

Run Code Online (Sandbox Code Playgroud)

这将打印(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
Run Code Online (Sandbox Code Playgroud)

它不应该打印 5,6,7,8... 等等。有没有办法杀死这个内部的 go 程序?

Bur*_*dar 5

您必须在 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)
Run Code Online (Sandbox Code Playgroud)