利用channel阻塞的特性,另外在我实际业务中需要协程去处理数据,下面我使用了 context 来解决。
package tool
import (
"context"
"fmt"
"log"
"reflect"
"runtime"
)
var PoolLimit chan struct{}
var XC *xc
type xc struct{}
/*
InitXcPond main函数时需初始化
num 协程限制数量
*/
func InitXcPond(num int) {
PoolLimit = make(chan struct{}, num)
XC = &xc{}
}
// Go 开始协程 使用上下文来传递函数需要处理的变量
func (x *xc) Go(f func(c context.Context), ctx context.Context) {
log.Println(fmt.Sprintf("当前:%s 正在使用协程,总协程数为:%d", runtime.FuncForPC(reflect.ValueOf(f).Pointer()).Name(), runtime.NumGoroutine()))
f(ctx)
<-PoolLimit
return
}
使用:
package test
import (
"common/tool"
"context"
"fmt"
"testing"
)
func init() {
tool.InitXcPond(20)
}
func TestPool(t *testing.T) {
for i:=0;i<=100;i++ {
c := context.Background()
c = context.WithValue(c,"myKey",i)
tool.PoolLimit <- struct{}{}
go tool.XC.Go(myTest,c)
}
}
func myTest(c context.Context) {
fmt.Println("key",c.Value("myKey"))
}
结果:协程池中协程维持在20个,其他5个是没有进入协程池的协程