下面是一个示例代码,演示了如何使用100个goroutine并发地处理一个长度为10000的slice,并将处理后的数据存入channel中:
package main
import (
"fmt"
)
func processChunk(chunk []int, resultChan chan<- []int) {
for i := 0; i < len(chunk); i++ {
// 在这里进行具体的处理操作
chunk[i] *= 2
}
resultChan <- chunk // 将处理完的chunk存入结果通道中
}
func main() {
const numChunks = 100 // 用100个goroutine处理slice
sliceSize := 10000 // slice大小为10000
// 创建一个长度为10000的slice,并初始化为随机数
slice := make([]int, sliceSize)
for i := 0; i < sliceSize; i++ {
slice[i] = i
}
// 创建一个结果通道,用于存储处理后的slice数据
resultChan := make(chan []int)
// 将slice分成numChunks个块,每块的大小为sliceSize/numChunks
chunkSize := sliceSize / numChunks
for i := 0; i < numChunks; i++ {
startIndex := i * chunkSize
endIndex := (i + 1) * chunkSize
if i == numChunks-1 { // 最后一块可能不够chunkSize大,需要特殊处理
endIndex = sliceSize
}
// 启动一个goroutine来处理当前块的数据
go processChunk(slice[startIndex:endIndex], resultChan)
}
// 等待所有goroutine处理完毕,并将处理结果合并到一个slice中
resultSlice := make([]int, sliceSize)
for i := 0; i < numChunks; i++ {
chunkResult := <-resultChan // 从结果通道中取出一个已处理的chunk
copy(resultSlice[i*chunkSize:], chunkResult)
}
// 检查结果是否正确
for i := 0; i < sliceSize; i++ {
if resultSlice[i] != i*2 {
fmt.Printf("Error: index %d = %d\n", i, resultSlice[i])
break
}
}
fmt.Println("All done!")
}
在上面的代码中,我们首先创建了一个10000个元素的slice,并将其分成了100个块,每个块大小为100。然后,我们启动了100个goroutine来并发处理这些块的数据。每个goroutine在执行完具体的处理操作之后,会将处理结果存入一个结果通道中。
最后,我们等待所有的goroutine处理完毕,并将它们的处理结果合并到一个最终的slice中。在这个例子中,我们只是简单地将各个块的处理结果拼接起来,但实际应用中可能需要更复杂的合并方式。最后,我们检查合并后的结果是否正确,并输出一条”All done!“的消息表示处理完成。




