多协程查询切片问题

题目描述:

假设有一个超长的切片,切片的元素类型为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
		}
	}
}

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部