golang goroutine 骚操作系列 动态数量
type mg struct {
max int
ch chan func()
pool chan struct{}
addGoRoutine *sync.Mutex
clearTime time.Duration
}
func newMg(max int, cleanTime time.Duration) mg {
res := mg{max, make(chan func(), max), make(chan struct{}, max), &sync.Mutex{}, cleanTime}
return res
}
func (itself *mg) exec(action func()) {
// 写入的地方可以判断是否需要动态新增一个goroutine
if len(itself.ch)+1 > len(itself.pool) && len(itself.pool) < itself.max {
itself.checkNeedNewGoRoutine()
}
itself.ch <- action
}
func (itself *mg) checkNeedNewGoRoutine() {
itself.addGoRoutine.Lock()
defer itself.addGoRoutine.Unlock()
if len(itself.pool) >= itself.max {
return
}
go func(mgo *mg) {
mgo.pool <- struct{}{}
defer func() {
<-mgo.pool
}()
timeout := time.After(itself.clearTime * time.Second)
for {
select {
case action := <-mgo.ch:
action()
timeout = time.After(itself.clearTime * time.Second)
case <-timeout:
break
}
}
}(itself)
}
func main() {
fmt.Println("success")
mgo := newMg(5, time.Second*3)
for i := 1; i <= 100; i++ {
mgo.exec(func(i int) func() {
return func() {
time.Sleep(time.Second)
fmt.Println(time.Now().Second(), i)
}
}(i))
}
time.Sleep(time.Second * 2)
}
本作品采用《CC 协议》,转载必须注明作者和本文链接