停止单个 goroutine 的最佳方法?

Joe*_*Joe 0 go goroutine

在我的程序中,我有几个 go-routines,它们本质上是在运行无休止的进程。为什么?你可能会问,长话短说这是我整个申请的目的,所以改变它是不可能的。我想让用户能够停止单个 go-routine。我知道我可以使用 channel 来通知 go-routines 停止,但是在某些情况下,我可能有 10 个 go-routines 正在运行而我只想停止 1。问题是 go-routines 的数量我想运行的是动态的并基于用户输入。对我来说,添加动态停止 go-routine 并允许单打停止而没有其他功能的最佳方法是什么?

小智 5

您需要设计一个地图来管理上下文。

假设您已经知道上下文的用法。它可能看起来像:

ctx, cancel := context.WithCancel(ctx.TODO())

go func(ctx){
    for {

        select {

           case <-ctx.Done():
                return
           default:
              // job
        }
    }
}(ctx)

cancel()
Run Code Online (Sandbox Code Playgroud)

好的,现在您可以将您的问题转换为另一个问题,它可能称为“如何管理许多 goroutine 的上下文”

type GoroutineManager struct{
    m sync.Map
}
func (g *GoroutineManager) Add(cancel context.CancelFunc, key string)) {
    g.m.Store(key, cancel)
}

func (g *GoroutineManager) KillGoroutine(key string) {
    cancel, exist := g.m.Load(key)
    if exist {
        cancel()
    }
}

Run Code Online (Sandbox Code Playgroud)

好的,现在你可以像这样管理你的 goroutine:

ctx, cancel := context.WithCancel(ctx.TODO())

manager.Add(cancel, "routine-job-1")
go func(ctx){
    for {

        select {

           case <-ctx.Done():
                return
           default:
              // job
        }
    }
}(ctx)


// kill it as your wish
manager.KillGoroutine("routine-job-1")
Run Code Online (Sandbox Code Playgroud)