相信大家在学习Go的过程中,都会看到类似这样一句话:"与传统的系统级线程和进程相比,协程的最大优势在于其‘轻量级’,可以轻松创建上百万个而不会导致系统资源衰竭"。那是不是意味着我们在开发过程中,可以随心所欲的调用协程,而不关心它的数量呢?
答案当然是否定的。我们在开发过程中,如果不对Goroutine加以控制而进行滥用的话,可能会导致服务程序整体崩溃。
下面是通过channel和sync.WaitGroup实现控制
//协程池
package main
import (
"fmt"
"sync"
"time"
)
//协程池
type Pool struct {
num int //go协程数
ch chan struct{}//任务队列
}
//初始化协程池
func NewPool(num int) *Pool {
return &Pool{
num: num,
ch: make(chan struct{},num),
}
}
var wg sync.WaitGroup
//任务处理函数
func Task(p *Pool) {
p.ch<- struct{}{}
wg.Add(1)
go func() {
//fmt.Println(time.Now())
time.Sleep(1*time.Second)
<-p.ch //一定要加,不取出会死锁
wg.Done()
}()
}
func main() {
//1.创建协程对象
p:=NewPool(50)
//2.创建任务
bT := time.Now() // 开始时间
for i := 0; i <100 ; i++ {
Task(p)
}
wg.Done()
close(p.ch)
eT := time.Since(bT) // 从开始到当前所消耗的时间
fmt.Println("Run time: ", eT)
}
有不对的地方欢迎指出