请参见以下示例。
type runner struct{}
func (r *runner) StopProcessing() {
// how to stop?
}
func (r *runner) StartProcessing() {
go func() {
for {
fmt.Println("doing stuff")
time.Sleep(1 * time.Second)
}
}()
}
如您所见,我有一个执行内容的结构,它正在“运行”。当我调用run.StartProcessing()
方法时,它开始运行。然后,它会在goroutine中触发一个不断运行的for{}
循环。很好,但我也希望能够停止此过程。我真的不知道如何实现这一目标。我们非常感谢您的帮助。
答案 0 :(得分:2)
您可以使用上下文获取超时和取消,而无需任何额外的API。
type runner struct{}
func (r *runner) StartProcessing(ctx context.Context) {
go func() {
for {
select {
case <-ctx.Done():
return
default:
}
fmt.Println("doing stuff")
time.Sleep(1 * time.Second)
}
}()
}
这使您可以灵活地设置超时或随时取消超时。您还可以利用现有的上下文,这些上下文可能要在您不知情的情况下超时或取消。
// normal timeout after 10 seconds
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()
run.StartProcessing(ctx)
// decide to cancel early
time.Sleep(3 * time.Second)
cancel()
答案 1 :(得分:-1)
通过使用一个通道发出何时发出goroutine信号。您的代码的相关部分看起来像这样
type runner struct {
stop chan bool
}
func (r *runner) StopProcessing() {
r.stop <- true
}
func (r *runner) StartProcessing() {
r.stop = make(chan bool)
go func() {
for {
fmt.Println("doing stuff")
time.Sleep(1 * time.Second)
select {
case _ = <-r.stop:
close(r.stop)
return
default:
}
}
}()
}
上看到完整的示例
答案 2 :(得分:-1)
您可以尝试类似的操作……您可能不需要原子的,但这可以工作。
package main
import (
"fmt"
"time"
"sync/atomic"
)
var trip = int64(0)
type runner struct{}
func (r *runner) StopProcessing() {
atomic.AddInt64(&trip, 1)
}
func (r *runner) StartProcessing() {
go func() {
for {
if trip > 0 {
break
}
fmt.Println("doing stuff")
time.Sleep(1 * time.Second)
}
}()
}
func newRunner() *runner {
return &runner{}
}
func main() {
run := newRunner()
run.StartProcessing()
// now wait 4 seconds and the kill the process
time.Sleep(4 * time.Second)
run.StopProcessing()
}