开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情
用go语言实现协程代码:总共有2万个任务,但同时只能有1000个任务并行,等待所有协程任务完成后退出程序。
package main
import (
"fmt"
"sync"
)
const (
taskCount = 20000
concurrentTaskCount = 1000
)
func main() {
var wg sync.WaitGroup
wg.Add(taskCount)
tasks := make(chan struct{}, concurrentTaskCount)
for i := 0; i < taskCount; i++ {
tasks <- struct{}{}
go func(taskNum int) {
defer func() {
<-tasks
wg.Done()
}()
// Do the task here
fmt.Printf("Task %d started\n", taskNum)
// ...
fmt.Printf("Task %d finished\n", taskNum)
}(i)
}
wg.Wait()
}
代码解释:
该代码实现了 2 万个任务,但同时只能有 1000 个任务并行的协程代码。使用了 Go 内置的 sync.WaitGroup 来等待所有任务完成后再退出程序。同时使用了一个带缓冲的通道 tasks,限制同时并行的任务数量,保证每次只有 1000 个任务并行执行。
关键代码解答
(1)上面的 <-tasks 是什么意思
"<-tasks" 是 Go 语言中的一个 channel 操作,它的意思是从 "tasks" 这个 channel 中读取一个数据。在 Go 语言中,channel 是一种特殊的数据结构,用来在协程间进行数据交换。读取 channel 的操作类似于读取一个数组中的数据,只不过在 channel 中读取的数据需要通过阻塞等待方式读取。
(2)上面的tasks <- struct{}{} 是什么意思
`"tasks <- struct{}{}" 是 Go 语言中的通道语法,意思是将空结构体 struct{}{} 发送到通道 tasks。通道是 Go 语言的一种用于实现协程间通信的数据结构,支持在不同协程间传递数据。
在这个代码中,通道 tasks 被用作信号,用于记录已完成的任务数量,其作用是限制同时运行的协程数量,并在所有协程完成后通知主程序退出。`