wg := sync.WaitGroup{}
for i :=0; i <9; i++{
wg.Add(1)
v := i //grpool.add() 的参数只能是不带参数的匿名函数 因此只能以设置临时变量的方式赋值
_ = grpool.Add(func(){
fmt.Println(v)
wg.Done()})}
wg.Wait()
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
打印结果
错误代码
注意:这是错误的演示,不要这么写~
wg := sync.WaitGroup{}
for i :=0; i <9; i++{
wg.Add(1)
_ = grpool.Add(func(){
fmt.Println(i)//打印结果都是9
wg.Done()})}
wg.Wait()
1.
2.
3.
4.
5.
6.
7.
8.
9.
打印结果
性能测试
使用for循环,开启一万个协程,分别使用原生goroutine和grpool执行。
看两者在内存占用和耗时方面的差别。
package main
import ("flag""fmt""github.com/gogf/gf/os/grpool""github.com/gogf/gf/os/gtime""log""os""runtime""runtime/pprof""sync""time")
func main(){//接收命令行参数
flag.Parse()//cpu分析
cpuProfile()//主逻辑
//demoGrpool()
demoGoroutine()//内存分析
memProfile()}
func demoGrpool(){
start := gtime.TimestampMilli()
wg := sync.WaitGroup{}
for i :=0; i <10000; i++{
wg.Add(1)
_ = grpool.Add(func(){
var m runtime.MemStats
runtime.ReadMemStats(&m)
fmt.Printf("运行中占用内存:%d Kb\n", m.Alloc/1024)time.Sleep(time.Millisecond)
wg.Done()})
fmt.Printf("运行的协程:", grpool.Size())}
wg.Wait()
fmt.Printf("运行的时间:%v ms \n", gtime.TimestampMilli()-start)select{}}
func demoGoroutine(){//start := gtime.TimestampMilli()
wg := sync.WaitGroup{}
for i :=0; i <10000; i++{
wg.Add(1)
go func(){//var m runtime.MemStats//runtime.ReadMemStats(&m)//fmt.Printf("运行中占用内存:%d Kb\n", m.Alloc/1024)time.Sleep(time.Millisecond)
wg.Done()}()}
wg.Wait()//fmt.Printf("运行的时间:%v ms \n", gtime.TimestampMilli()-start)}
var cpuprofile = flag.String("cpuprofile","","write cpu profile `file`")
var memprofile = flag.String("memprofile","","write memory profile to `file`")
func cpuProfile(){
if *cpuprofile !=""{
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatal("could not create CPU profile: ", err)}
if err := pprof.StartCPUProfile(f); err != nil {//监控cpu
log.Fatal("could not start CPU profile: ", err)}
defer pprof.StopCPUProfile()}}
func memProfile(){
if *memprofile !=""{
f, err := os.Create(*memprofile)
if err != nil {
log.Fatal("could not create memory profile: ", err)}
runtime.GC()// GC,获取最新的数据信息
if err := pprof.WriteHeapProfile(f); err != nil {// 写入内存信息
log.Fatal("could not write memory profile: ", err)}
f.Close()}}