一个把Context,Timer,Goroutine和Channel结合起来的例子
kevinyan815 opened this issue · 0 comments
kevinyan815 commented
用多个goroutine在一个超级长的切片中查找目标整数,限时5秒。在找到目标值或者超时后立刻结束所有goroutine的执行。
package main
import (
"context"
"fmt"
"os"
"time"
)
func main() {
timer := time.NewTimer(time.Second * 5)
data := []int{1, 2, 3, 10, 999, 8, 345, 7, 98, 33, 66, 77, 88, 68, 96}
dataLen := len(data)
size := 3
target := 345
ctx, cancel := context.WithCancel(context.Background())
resultChan := make(chan bool)
for i := 0; i < dataLen; i += size {
end := i + size
if end >= dataLen {
end = dataLen - 1
}
go SearchTarget(ctx, data[i:end], target, resultChan)
}
select {
case <-timer.C:
fmt.Fprintln(os.Stderr, "Timeout! Not Found")
cancel()
case <- resultChan:
fmt.Fprintf(os.Stdout, "Found it!\n")
cancel()
}
time.Sleep(time.Second * 2)
}
func SearchTarget(ctx context.Context, data []int, target int, resultChan chan bool) {
for _, v := range data {
select {
case <- ctx.Done():
fmt.Fprintf(os.Stdout, "Task cancelded! \n")
return
default:
}
// 模拟一个耗时查找,这里只是比对值,真实开发中可以是其他操作
fmt.Fprintf(os.Stdout, "v: %d \n", v)
time.Sleep(time.Millisecond * 1500)
if target == v {
resultChan <- true
return
}
}
}