前言
怎么用channel来控制并发呢?我们最直观的想法就是构造一个带缓存的channel,一个协程在执行前先往里面占一个坑,执行完后再释放这个坑位,这样一来始终只有固定数量的协程在同时执行,从而达到并发控制的效果。
实现
open-falcon里使用第三方包 github.com/toolkits/concurrent/semaphore 来实现这种效果,先上代码:
package main import( "fmt" "time" nsema "github.com/toolkits/concurrent/semaphore" //查看该源码,其实就是利用了channel来做并发控制 ) func main(){ concurrentNum := 2 //设置并发数2 sema := nsema.NewSemaphore(concurrentNum) for i:=0; i<8; i++ { sema.Acquire() //先占一个坑,往channel里写一个数据 go func(num int){ defer sema.Release() //释放坑位 fmt.Printf("%d, get sema, ok\n", num) time.Sleep(1*time.Second) }(i) } // keep alive time.Sleep(5*time.Second) }
结构体
type Semaphore struct { bufSize int channel chan int8 //带缓存的channel }
Acquire()方法
func (this *Semaphore) Acquire() { this.channel <- int8(0) //往cannel里写入一条数据 }
Release()方法
func (this *Semaphore) Release() { <-this.channel //从channel里拿出一条数据 }