3 回答
TA贡献1804条经验 获得超3个赞
除了Burak回答的上下文之外,您还可以使用退出频道。
package main
import (
"fmt"
"math/rand"
"time"
)
func foo(channel, quit chan string, i int) {
channel <- fmt.Sprintf("goroutine %d started!", i)
for {
rand.Seed(time.Now().UnixNano())
time.Sleep(time.Duration(rand.Intn(500)+500) * time.Millisecond)
quit <- fmt.Sprintf("goRoutine %d completed!", i)
}
}
func main() {
channel := make(chan string)
quit := make(chan string)
for i := 0; i < 3; i++ {
go foo(channel, quit, i)
}
for {
select {
case update:= <-channel:
fmt.Println(update)
case quit:= <-quit:
fmt.Println(quit)
return
}
}
}
TA贡献1865条经验 获得超7个赞
您可以使用上下文:
ctx, cancel:= context.WithCancel(context.Background())
for ... {
go func() {
defer cancel() // cancel context once this goroutine ends
doStuff(ctx)
}()
}
您必须在戈鲁丁中检查上下文取消:
func doStuff(ctx context.Context) {
...
if ctx.Err()!=nil {
// Canceled, return
return
}
...
}
这并不能保证一旦上下文被取消,其他戈鲁廷将立即结束,但它保证,如果您正确检查上下文取消,所有戈鲁廷最终都会结束。
TA贡献1853条经验 获得超9个赞
您可以使用上下文和错误组。一些类似的东西...
package main
import (
"context"
"fmt"
"math/rand"
"os"
"time"
"golang.org/x/sync/errgroup"
)
func doStuff(ctx context.Context, i int) error {
count := 0
for ctx.Err() == nil {
// do the stuff
time.Sleep(time.Millisecond * time.Duration(rand.Intn(500)))
count++
if count > 6 { // error condition
fmt.Fprintf(os.Stdout, "%v reached count %v\n", i, count)
return fmt.Errorf("Error %v, count %v\n", i, count)
}
}
fmt.Fprintf(os.Stdout, "Killed %v @ count %v\n", i, count)
return ctx.Err()
}
func main() {
rand.Seed(int64(time.Now().Nanosecond()))
ctxWc, _ := context.WithCancel(context.Background())
g, ctx := errgroup.WithContext(ctxWc)
for i := 0; i < 5; i++ {
i := i
g.Go(func() error {
return doStuff(ctx, i)
})
}
err := g.Wait()
fmt.Println("The End")
if err != nil {
fmt.Println(err)
}
}
- 3 回答
- 0 关注
- 86 浏览
添加回答
举报