实际上就是控制并发执行goroutine的数量,这里给出两种解决方法,使用chan的方法更普遍
package main
import (
"context"
"golang.org/x/sync/semaphore"
"sync"
)
type Task int
func handle1(tasks []Task, execute func(task Task)) {
wg := sync.WaitGroup{}
sema := semaphore.NewWeighted(10)
ctx := context.TODO()
for i, _ := range tasks {
wg.Add(1)
task := tasks[i]
go func() {
defer func() {
wg.Done()
sema.Release(1)
}()
// execute task
err := sema.Acquire(ctx, 1)
if err != nil {
panic(err)
}
execute(task)
}()
}
wg.Wait()
}
func handle(tasks []Task, execute func(task Task)) {
wg := sync.WaitGroup{}
ch := make(chan struct{}, 10)
for i, _ := range tasks {
ch <- struct{}{}
wg.Add(1)
task := tasks[i]
go func() {
defer wg.Done()
// execute task
execute(task)
<-ch
}()
}
wg.Wait()
}
测试用例
package main
import (
"fmt"
"testing"
"time"
)
func TestCtl(t *testing.T) {
handle([]Task{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, func(task Task) {
fmt.Println(task)
time.Sleep(5 * time.Second)
})
}