go 怎么等待所有的协程完成_Go语言学习基础-工人池、等待组、速率限制

Worker Pool工人池

下面的例子使用协程和通道实现工人池,程序同时运行了几个工人实例。这些工人从通道jobs中获取工作,并发送结果到通道results。每个工人函数休眠一秒钟来模拟一项耗时的任务。

使用工人池时,需要向工人发送工作并收集他们的结果,为此创建了2个通道。启动3个工人协程,开始时由于还没有作业而被阻塞。向通道jobs中发送5个作业任务,然后关闭该通道,以表明这是所有的工作。最后,收集所有的工作结果,这也确保了工人协程能正常结束。等待多个协程的另一种方法是使用WaitGroup。尽管总共有大约5秒钟的工作,因为有3个协程同时执行,因此这个程序只用了大约2秒钟。

2f97e0540b63720dea6d0ebe8a4474d4.png

结果:

$ time go run worker-pools.go

worker 1 started job 1

worker 2 started job 2

worker 3 started job 3

worker 1 finished job 1

worker 1 started job 4

worker 2 finished job 2

worker 2 started job 5

worker 3 finished job 3

worker 1 finished job 4

worker 2 finished job 5

real 0m2.358s

WaitGroup等待组

要等待多个协程完成,可以使用等待组。注意,等待组必须通过指针传递给函数。

等待组用于等待所有启动的协程完成工作。当启动一个协程时递增一次等待组的计数器。主函数调用等待组的Wait方法阻塞,直到等待组计数器返回0后再继续往下执行;在协程中return返回函数时,需要先调用等待组的Done方法减少等待组的计数器,表示本协程结束执行,所有的协程都要通知他们已经完成了。每个协程的启动和完成的顺序可能不同。

d7a0c8914a593ef7fb4ff49a80ec0b50.png

结果:

$ go run waitgroups.go

Worker 5 starting

Worker 3 starting

Worker 4 starting

Worker 1 starting

Worker 2 starting

Worker 4 done

Worker 1 done

Worker 2 done

Worker 5 done

Worker 3 done

Rate Limiting速率限制

速率限制是控制资源利用、维护服务质量的重要机制。Go通过协程、通道和计时器优雅实现速率限制。

首先,是常规速率限制。假设要限制对传入请求的处理。创建请求通道requests,创建计时器time.Tick,每隔200毫秒触发一次,以此限制从通道接收值的速率,因此把速率限制方案中使用的计时器通道叫作速率调节器。在处理每个请求服务之前,通过阻塞限制器信道的接收,从而限制了请求的处理速率。

有时,可能希望在速率限制方案中允许突发请求,但同时又保留整个速率限制,可以通过带缓冲的速率限制器通道来实现突发速率限制。通道burstyLimiter将允许最多3个事件的突发,常规情况下每隔200毫秒,向通道添加一个新值。现在再模拟5个传入请求,其中前3个将受益于burstyLimiter的突发能力。运行程序,看到第一批请求按需要每200毫秒被处理一次。对于第二批请求,由于burstable速率限制,会立即服务前3个,然后服务其余2个,每个延迟约200毫秒。

1c17783997d852cd57ef27f02b3856f2.png

结果:

$ go run rate-limiting.go

request 1 2012-10-19 00:38:18.687438 +0000 UTC

request 2 2012-10-19 00:38:18.887471 +0000 UTC

request 3 2012-10-19 00:38:19.087238 +0000 UTC

request 4 2012-10-19 00:38:19.287338 +0000 UTC

request 5 2012-10-19 00:38:19.487331 +0000 UTC

request 1 2012-10-19 00:38:20.487578 +0000 UTC

request 2 2012-10-19 00:38:20.487645 +0000 UTC

request 3 2012-10-19 00:38:20.487676 +0000 UTC

request 4 2012-10-19 00:38:20.687483 +0000 UTC

request 5 2012-10-19 00:38:20.887542 +0000 UTC

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值