Go study notes - work pool, waiting group, rate limit
1. Working poolWorker Pools
Worker pools allow goroutine
safe sharing of resources.
Passed goroutine
and channel
achieved.
func worker(id int,jobs <-chan int,results chan<- int){
for j := range jobs{
fmt.Println("worker",id,"processing job",j)
time.Sleep(time.Second * 2)
results <- j * 2 // 接收通道接收任务后,向results通道发送结果
}
}
func main(){
jobs := make(chan int,100)
results := make(chan int,100)
for w := 1;w <= 3;w++{
go worker(w,jobs,results) // 创建3个工作池
}
for j:=1;j<=9;j++{
jobs <- j // 向工作池接收通道发送任务
}
close(jobs) // 关闭jobs通道
for i:=1;i<=9;i++{
<-results // results通道接收到结果,工作池结束
}
}
Define the working pool worker
, the parameters jobs
are the receiving channel, results
the sending channel, id
and the working pool number.
The worker pool runs in parallel.
2. Waiting groupWaitGroups
WaitGroups
Waiting for multiple coroutines to complete can be used goroutine
.
By sync.WaitGroup
defining a receiver, you can use the waiting group function.
var wg sync.WaitGroup
wg.Done()
WaitGroup
When making function parameters, use pointers.
func working(id int,wg *sync.WaitGroup){
defer wg.Done()
fmt.Println("Worker",id,"starting") // 先输出
time.Sleep(time.Second * 6)
fmt.Println("Worker",id,"done") // 6秒后输出
}
func main(){
var wg sync.WaitGroup
for i:=1;i<=5;i++{
wg.Add(1)
go working(i,&wg)
time.Sleep(time.Second) // 输出间隔1秒
}
wg.Wait()
}
//Worker 1 starting
//Worker 2 starting
//Worker 3 starting
//Worker 4 starting
//Worker 5 starting
//Worker 1 done
//Worker 2 done
//Worker 3 done
//Worker 4 done
//Worker 5 done
//主函数在运行之后,每间隔1秒输出一次`Worker 1 starting`,输出5次后,等待1秒,再输出`Worker 1 done`。
Use sleep
to simulate a blocked state.
According to the example, it can be seen that when it is added , the main function will end after WaitGroup
all the operations are completed.goroutine
.Done()
: Returnsgoroutine
the status of all finished runs.Add()
: add parameter toWaitGroup
counter.Wait()
: Wait forgoroutine
the end of the operation and end the main program
3. Rate limitRate Limiting
Rate limiting is an important way to control resource utilization and quality of service.
Through goroutine
, channel
, ticker
to achieve.
func main(){
requests := make(chan int,5)
for i := 1;i <= 5;i++{
requests <- i
}
close(requests)
limiter := time.Tick(time.Second)
for req := range requests{
<- limiter
fmt.Println("request",req,time.Now())
}
// 上部分模拟限制速率的传输
burstyLimiter := make(chan time.Time,3)
for i := 0;i<3;i++{
burstyLimiter <- time.Now()
}
go func() {
for t := range time.Tick(time.Second){
burstyLimiter <- t
}
}()
// 模拟整体的速率控制
burstyRequests := make(chan int,5)
for i:=1;i<=5;i++{
burstyRequests <- i
}
close(burstyRequests)
for req := range burstyRequests{
<- burstyLimiter
fmt.Println("request",req,time.Now())
}
// 模拟超过5个介入请求,在通道缓冲影响下的结果
}