如果我们无法从传递给该例程的通道侦听,如何停止 goroutine



我遇到了一个问题 w.r.t goroutines。假设有一个通道,我们从main通过goroutine传递了这个通道。现在,如果我们无法从主频道收听此通道(以防在收听前发生返回/恐慌)。例行程序不会停止。万一出错,如何停止这个goroutine?

在 goroutine 中多次调用函数的情况下,例程的数量不断增加。

package main
import (
    "fmt"
    "runtime"
)
func test(a chan string) {
    defer func() {
        close(a)
        fmt.Println("channel close")
    }()
    fmt.Println("sending to channel")
    a <- "1"
    fmt.Println("sent to channel")
}
func method() string {
    fmt.Println("method starting no. of routine=>",
        runtime.NumGoroutine())
    b := make(chan string)
    go test(b)
    fmt.Println("method current no. of routine=>",
        runtime.NumGoroutine())
    return "error" //if this is executed the routines keeps on
    //increasing
    a := <-b
    return a
}
func main() {
    defer fmt.Println("final main no. of routine=>",
        runtime.NumGoroutine())
    i := 0
    //firing 10 request for method
    for {
        if i < 10 {
               fmt.Println(method())
               i++
        } else {
               break
        }
    }
}

输出:

method starting no. of routine=> 1
method current no. of routine=> 2
error
method starting no. of routine=> 2
method current no. of routine=> 3
error
method starting no. of routine=> 3
method current no. of routine=> 4
error

.....像这样继续增加

程可以按上下文停止。在使用上下文之前,您应该知道只有带有循环的例程是预期的停止控制,那些可死的例程不需要停止。

上下文示例:

func main(){
    ctx, cancel := context.WithCancel(context.Background())
    go func(c context.Context){
        for {
            select{
                case <-c.Done():
                   fmt.Println("exit success")
                default:
                   // service
                   fmt.Println("my logic service loop")
            }    
        }
    }(ctx)
    time.Sleep(5 * time.Second)
   cancel()
}

最新更新