Goroutine并发控制
Posted followyou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Goroutine并发控制相关的知识,希望对你有一定的参考价值。
创建协程
jobCount := 10
// sync.WaitGroup 监控所有协程的状态,从而保证主协程结束时所有的子协程已经退出
group := sync.WaitGroup{}
for i:=0;i < jobCount;i++ {
group.Add(1)
go func(i int) {
fmt.Println("task ",i)
time.Sleep(time.Second) // 刻意睡 1 秒钟,模拟耗时
group.Done()
}(i)
fmt.Printf("index: %d,goroutine Num: %d
", i, runtime.NumGoroutine())
}
group.Wait()
运行结果:
index: 0,goroutine Num: 2
index: 1,goroutine Num: 3
task 0
index: 2,goroutine Num: 4
index: 3,goroutine Num: 5
task 3
task 2
index: 4,goroutine Num: 6
index: 5,goroutine Num: 7
index: 6,goroutine Num: 8
task 4
index: 7,goroutine Num: 9
task 6
index: 8,goroutine Num: 10
index: 9,goroutine Num: 11
task 7
task 8
task 1
task 9
task 5
可以看到总共有11个协程,其中一个是主协程,其他十个是子协程,为了让主协程等待所有的子协程执行完毕后再退出,使用 sync.WaitGroup 监控所有协程的状态,从而保证主协程结束时所有的子协程已经退出。
实际生产中,产生的goroutine的数量,是巨大,但是这种简单直接的方式就显得不那么高效了。CPU同一时间只能处理一个Goroutine,大量job的情况将会出现大量的Goroutine等待,以致于造成资源的浪费。
控制Gorutine的数量
// 控制 Goroutine 数量
jobCount := 10
group := sync.WaitGroup{}
// 规定chan容量为3
jobsChan := make(chan int,3)
// 起3个worker
workerCount := 3
for w:=0; w <= workerCount; w++ {
go func(w int){
for j := range jobsChan {
fmt.Printf("worker %d get chan msg %d
",w,j)
time.Sleep(time.Second)
group.Done()
}
}(w)
}
// 发布消息到chan
for j :=0; j < jobCount; j++ {
jobsChan <- j
group.Add(1)
fmt.Printf("index: %d,goroutine Num: %d
", j, runtime.NumGoroutine())
}
group.Wait()
worker 1 get chan msg 0
index: 0,goroutine Num: 5
index: 1,goroutine Num: 6
worker 0 get chan msg 1
worker 2 get chan msg 2
index: 2,goroutine Num: 5
index: 3,goroutine Num: 5
index: 4,goroutine Num: 5
index: 5,goroutine Num: 5
index: 6,goroutine Num: 5
worker 3 get chan msg 3
worker 0 get chan msg 4
worker 1 get chan msg 7
index: 7,goroutine Num: 5
worker 2 get chan msg 5
index: 8,goroutine Num: 5
index: 9,goroutine Num: 5
worker 3 get chan msg 6
worker 0 get chan msg 8
worker 3 get chan msg 9
以上是关于Goroutine并发控制的主要内容,如果未能解决你的问题,请参考以下文章
高并发实时弹幕系统 并发数一定是可以进行控制的 每个需要异步处理开启的 Goroutine(Go 协程)都必须预先创建好固定的个数,如果不提前进行控制,那么 Goroutine 就随时存在爆发的可
全栈编程系列SpringBoot整合Shiro(含KickoutSessionControlFilter并发在线人数控制以及不生效问题配置启动异常No SecurityManager...)(代码片段