推荐答案
在 Go 语言中,可以通过使用 goroutine 和 channel 来控制并发度。具体来说,可以使用带缓冲的 channel 来限制同时运行的 goroutine 数量。以下是一个示例代码:
// www.javascriptcn.com code example
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, jobs <-chan int, results chan<- int, wg *sync.WaitGroup) {
defer wg.Done()
for job := range jobs {
fmt.Printf("Worker %d started job %d\n", id, job)
time.Sleep(time.Second) // 模拟工作
fmt.Printf("Worker %d finished job %d\n", id, job)
results <- job * 2
}
}
func main() {
const numJobs = 10
const numWorkers = 3
jobs := make(chan int, numJobs)
results := make(chan int, numJobs)
var wg sync.WaitGroup
// 启动 worker
for w := 1; w <= numWorkers; w++ {
wg.Add(1)
go worker(w, jobs, results, &wg)
}
// 发送任务
for j := 1; j <= numJobs; j++ {
jobs <- j
}
close(jobs)
// 等待所有 worker 完成
wg.Wait()
close(results)
// 收集结果
for result := range results {
fmt.Println("Result:", result)
}
}在这个示例中,numWorkers 控制了并发度,即同时运行的 goroutine 数量。通过 jobs 通道的缓冲大小和 numWorkers 的数量,可以有效地控制并发度。
本题详细解读
1. 并发度的概念
并发度(Concurrency Level)指的是在同一时间内可以同时执行的任务数量。在 Go 语言中,goroutine 是轻量级的线程,可以轻松创建成千上万个 goroutine。然而,过多的 goroutine 可能会导致资源耗尽或性能下降,因此需要控制并发度。
2. 使用带缓冲的 channel 控制并发度
在 Go 语言中,channel 是用于在 goroutine 之间进行通信的主要机制。通过使用带缓冲的 channel,可以限制同时运行的 goroutine 数量。具体步骤如下:
- 创建带缓冲的
channel:jobs := make(chan int, numJobs),其中numJobs是任务的数量,numWorkers是并发度。 - 启动固定数量的
goroutine:通过for循环启动numWorkers个goroutine,每个goroutine从jobs通道中接收任务并处理。 - 发送任务到
channel:将任务发送到jobs通道中,goroutine会自动从通道中取出任务并处理。 - 等待所有
goroutine完成:使用sync.WaitGroup来等待所有goroutine完成任务。
3. 示例代码解析
worker函数:每个worker从jobs通道中接收任务,处理完成后将结果发送到results通道中。main函数:- 创建
jobs和results通道。 - 启动
numWorkers个goroutine。 - 发送任务到
jobs通道。 - 关闭
jobs通道以通知worker没有更多任务。 - 使用
sync.WaitGroup等待所有worker完成。 - 关闭
results通道并收集结果。
- 创建
通过这种方式,可以有效地控制并发度,避免资源耗尽和性能问题。