停止单个 goroutine 的最佳方法?
Best way to stop a single goroutine?
在我的程序中,我有几个 go-routines,它们本质上是 运行ning 无穷无尽的进程。为什么?你可能会问,长话短说,这是我整个申请的目的,所以改变它是不可能的。我想让用户能够停止单个 go-routine。我知道我可以使用 channel 来通知 go-routines 停止,但是在某些情况下,我有 10 个 go-routines 运行ning 而我只想停止 1 个。问题是我想要 运行 的 go-routines 数量是动态的,并且基于用户输入。对我来说,添加动态停止 go-routine 的能力并允许在没有休息的情况下停止单身的最佳方法是什么?
您需要设计一个地图来管理上下文。
假设您已经知道上下文的用法。它可能看起来像:
ctx, cancel := context.WithCancel(ctx.TODO())
go func(ctx){
for {
select {
case <-ctx.Done():
return
default:
// job
}
}
}(ctx)
cancel()
好的,现在您可以将您的问题转换为另一个问题,它可能叫做 'how to manage contexts of many 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()
}
}
好的,现在您可以像这样管理您的 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")
在我的程序中,我有几个 go-routines,它们本质上是 运行ning 无穷无尽的进程。为什么?你可能会问,长话短说,这是我整个申请的目的,所以改变它是不可能的。我想让用户能够停止单个 go-routine。我知道我可以使用 channel 来通知 go-routines 停止,但是在某些情况下,我有 10 个 go-routines 运行ning 而我只想停止 1 个。问题是我想要 运行 的 go-routines 数量是动态的,并且基于用户输入。对我来说,添加动态停止 go-routine 的能力并允许在没有休息的情况下停止单身的最佳方法是什么?
您需要设计一个地图来管理上下文。
假设您已经知道上下文的用法。它可能看起来像:
ctx, cancel := context.WithCancel(ctx.TODO())
go func(ctx){
for {
select {
case <-ctx.Done():
return
default:
// job
}
}
}(ctx)
cancel()
好的,现在您可以将您的问题转换为另一个问题,它可能叫做 'how to manage contexts of many 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()
}
}
好的,现在您可以像这样管理您的 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")