题目描述:
假设有一个超长的切片,切片的元素类型为int,切片中的元素为乱序排序。限时5秒,使用多个goroutine查找切片中是否存在给定的值,在查找到目标值或者超时后立刻结束所有goroutine的执行。
比如,切片 [23,32,78,43,76,65,345,762,......915,86]
,查找目标值为 345 ,如果切片中存在,则目标值输出"Found it!"
并立即取消仍在执行查询任务的goroutine
。
如果在超时时间未查到目标值程序,则输出"Timeout!Not Found"
,同时立即取消仍在执行的查找任务的goroutine
。
思路:
将切片分成多个部分并使用多个goroutine同时查找目标值。使用一个带超时的上下文来控制查找的超时,以及一个sync.WaitGroup
来等待所有goroutine完成。当找到目标值或超时时,取消所有仍在执行查找任务的goroutine。
实现:
package main
import (
"context"
"fmt"
"math/rand"
"sync"
"time"
)
func main() {
data := make([]int, 9999999)
for i := range data {
data[i] = rand.Intn(9999999)
}
target := 345 //目标值
startTime := time.Now()
fmt.Println("Start time:", startTime)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) // 超时时间
defer cancel()
var wg sync.WaitGroup
found := make(chan struct{})
parts := 20
for i := 0; i < parts; i++ { //
wg.Add(1)
go func(i int) {
defer wg.Done()
SearchTarget(ctx, data[i*(len(data)/parts):(i+1)*(len(data)/parts)], target, found)
}(i)
}
select {
case <-found:
fmt.Println("Found it!")
case <-ctx.Done():
fmt.Println("Timeout!Not Found")
}
cancel()
wg.Wait()
endTime := time.Now()
fmt.Println("End time:", endTime)
elapsed := endTime.Sub(startTime)
fmt.Println("Elapsed time:", elapsed)
}
func SearchTarget(ctx context.Context, data []int, target int, found chan struct{}) {
for _, i := range data {
if ctx.Err() != nil {
return
}
if target == i {
select {
case found <- struct{}{}:
case <-ctx.Done():
}
return
}
}
}