go控制并发数
package main
import (
"fmt"
"log"
"sync"
"time"
)
type Glimit struct {
n int
c chan struct{}
}
// 初始化Glimit结构体
func New_workers(max_goroutine int) (*Glimit, error) {
if max_goroutine <= 0 {
return nil, fmt.Errorf("max_goroutine must be greater than 0")
}
return &Glimit{
n: max_goroutine,
c: make(chan struct{}, max_goroutine),
}, nil
}
// 在限制内运行f函数
func (g *Glimit) Run(f func() error) {
wg.Add(1)
g.c <- struct{}{} // 阻塞直到有空闲槽位
go func() {
defer func() {
if r := recover(); r != nil {
log.Printf("panic occurred in goroutine with msg : %v", r)
}
//log.Println(`通道被释放`)
<-g.c
wg.Done()
}()
if err := f(); err != nil {
log.Printf("Function execution failed with error: %v", err)
}
}()
}
var wg = sync.WaitGroup{}
func main() {
number := 8
g, err := New_workers(3) // 定义一次最多使用3个并发
if err != nil {
log.Fatalf("Failed to initialize Glimit: %v", err)
}
for i := 0; i < number; i++ {
value := i // value只在for循环体里有效
// 在循环里定义每次要执行的函数
goFunc := func() error {
// 做一些业务逻辑处理
log.Printf(" %v go func: %d \n", time.Now(), value)
// time.Sleep(time.Second)
// 模拟一个可能发生的错误
if value == 5 {
return fmt.Errorf("simulated error at value: %d", value)
//panic(fmt.Errorf("simulated error at value: %d", value))
}
return nil
}
g.Run(goFunc)
}
wg.Wait() // 等待结束
log.Println("ALL DONE!")
}
优化后的代码
浙公网安备 33010602011771号