golang 高并发主要是依靠sync包下的api实现,首先就是WaitGroup:
先说说WaitGroup的用途:它能够一直等到所有的goroutine执行完成,并且阻塞主线程的执行,直到所有的goroutine执行完成。
WaitGroup总共有三个方法:Add(delta int),Done(),Wait()。简单的说一下这三个方法的作用。
Add:添加或者减少等待goroutine的数量
Done:相当于Add(-1)
Wait:执行阻塞,直到所有的WaitGroup数量变成0
代码:
type Worker struct {
quit chan bool
}
func NewWorker() Worker {
return Worker{
quit: make(chan bool)}
}
// Start method starts the run loop for the worker, listening for a quit channel in
// case we need to stop it
func (w Worker) Start() {
go func() {
for {
select {
case <-JobQueue:
// we have received a work request.
doTask()
case <-w.quit:
// we have received a signal to stop
return
}
}
}()
}
// Stop signals the worker to stop listening for work requests.
func (w Worker) Stop() {
go func() {
w.quit <- true
}()
}
Job类:
type Job struct {
}
var JobQueue chan Job = make(chan Job, MaxQueue)
func doTask() {
//耗时炒作(模拟)
time.Sleep(200 * time.Millisecond)
wg.Done()
}
//这里模拟的http接口,每次请求抽象为一个job
func handle() {
//wg.Add(1)
job := Job{}
JobQueue <- job
}
var (
MaxWorker = 1000
MaxQueue = 200000
wg sync.WaitGroup
)
Dispatcher 类:
type Dispatcher struct {
}
func NewDispatcher() *Dispatcher {
return &Dispatcher{}
}
func (d *Dispatcher) Run() {
// starting n number of workers
for i := 0; i < MaxWorker; i++ {
worker := NewWorker()
worker.Start()
}
}
测试执行代码:
func Benchmark_handle(b *testing.B) {
runtime.GOMAXPROCS(runtime.NumCPU())
d := NewDispatcher()
d.Run()
for i:=0;i<10000;i++ {
wg.Add(1)
handle()
}
wg.Wait()
}