go批量执行,并返回批量执行的返回值

方式1

package main

import (
	"fmt"
	"sync"
	"time"
)

func doWork(id int, resultChan chan<- int, wg *sync.WaitGroup) {
	defer wg.Done() // 表示goroutine完成
	time.Sleep(time.Duration(id) * time.Second) // 模拟工作负载
	resultChan <- id * 2 // 发送结果到channel
}

func main() {
	var wg sync.WaitGroup
	resultChan := make(chan int, 5) // 假设我们有5个goroutine

	// 启动多个goroutine
	for i := 1; i <= 5; i++ {
		wg.Add(1) // 增加WaitGroup计数
		go doWork(i, resultChan, &wg)
	}

	// 等待所有goroutine完成
	go func() {
		wg.Wait() // 等待所有goroutine完成
		close(resultChan) // 完成所有工作后关闭channel
	}()

	// 收集所有结果
	for result := range resultChan {
		fmt.Println("Result:", result)
	}
}

方式2

package main

import (
	"fmt"
	"time"
)

func doWork(id int, resultChan chan<- int, doneChan chan<- struct{}) {
	time.Sleep(time.Duration(id) * time.Second) // 模拟工作负载
	resultChan <- id * 2 // 发送结果到channel
	doneChan <- struct{}{} // 发送信号表示完成
}

func main() {
	resultChan := make(chan int, 5) // 存储结果
	doneChan := make(chan struct{}, 5) // 信号channel,表示5个goroutine完成

	for i := 1; i <= 5; i++ {
		go doWork(i, resultChan, doneChan)
	}

	// 收集所有结果
	for i := 1; i <= 5; i++ {
		result := <-resultChan
		fmt.Println("Result:", result)
		<-doneChan // 等待一个goroutine完成
	}
	close(resultChan) // 完成后关闭channel
}

方式3 推荐

package main

import (
	"fmt"
	"sync"
)

// calculateSum 计算从start到end(含)的整数和
func calculateSum(start, end int) int {
	sum := 0
	for i := start; i <= end; i++ {
		sum += i
	}
	return sum
}

func main() {
	var mu sync.Mutex                        // 互斥锁,用于保护共享变量
	var cond = sync.Cond{L: &mu}             // 条件变量,初始化时传入互斥锁
	numGoroutine := 5                        // 并发执行的goroutine数量
	partialSums := make([]int, numGoroutine) // 存储每个goroutine计算的部分和
	completed := 0                           // 完成的goroutine计数

	// 计算每个goroutine负责的范围
	chunkSize := 10000 / numGoroutine

	// 启动numGoroutine个goroutine执行任务
	for i := 0; i < numGoroutine; i++ {
		go func(id int) {
			start := id*chunkSize + 1
			end := (id + 1) * chunkSize
			// 处理边界情况,确保最后一个goroutine包含10000
			if id == numGoroutine-1 {
				end = 10000
			}
			partialSum := calculateSum(start, end)
			mu.Lock()
			partialSums[id] = partialSum
			completed++
			if completed == numGoroutine {
				cond.Broadcast() // 如果所有任务都完成了,广播通知
			}
			mu.Unlock()
		}(i)
	}

	// 等待所有任务完成
	mu.Lock()
	for completed < numGoroutine {
		cond.Wait() // 等待条件变量通知
	}
	mu.Unlock()

	// 计算总和
	totalSum := 0
	for _, partialSum := range partialSums {
		totalSum += partialSum
	}

	// 打印总和
	fmt.Println("Total sum:", totalSum)
}
posted @ 2024-12-03 09:51  朝阳1  阅读(25)  评论(0)    收藏  举报