2024-03-12
学习
00
请注意,本文编写于 458 天前,最后修改于 291 天前,其中某些信息可能已经过时。

目录

题目
题解

在网上看到的比较考验思路的题,学习学习罢-

题目

假设有一个超长的切片,切片的元素类型为int,切片中的元素为乱序排序。限时5秒,使用多个goroutine查找切片中是否存在给定的值,在查找到目标值或者超时后立刻结束所有goroutine的执行。

比如,切片 [23,32,78,43,76,65,345,762,......915,86],查找目标值为 345 ,如果切片中存在,则目标值输出"Found it!"并立即取消仍在执行查询任务的goroutine。

如果在超时时间未查到目标值程序,则输出"Timeout!Not Found",同时立即取消仍在执行的查找任务的goroutine。

题解

思路:

首先创建一个通道来通知所有的 Goroutine 停止执行。

启动多个 Goroutine 来并行地在切片中查找目标值。

使用 time.After 创建一个超时通道,当超时发生时,通过停止通道通知所有 Goroutine 停止。

每个 Goroutine 在找到目标值时,通过停止通道通知其他 Goroutine 停止,并输出结果。

go
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 } } }

本文作者:han

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!