diff --git a/ants_benchmark_test.go b/ants_benchmark_test.go index 0eaa4a4..f63d114 100644 --- a/ants_benchmark_test.go +++ b/ants_benchmark_test.go @@ -27,7 +27,7 @@ import ( "testing" "time" - "github.com/panjf2000/ants" + "github.com/liyonglion/ants" ) const ( @@ -42,9 +42,9 @@ const ( YiB // 1208925819614629174706176 ) const ( - RunTimes = 10000000 + RunTimes = 1000000 Param = 100 - AntsSize = 1000 + AntsSize = 50000 TestSize = 10000 ) @@ -68,6 +68,7 @@ func demoPoolFunc(args interface{}) error { func BenchmarkGoroutineWithFunc(b *testing.B) { var wg sync.WaitGroup + for i := 0; i < b.N; i++ { for j := 0; j < RunTimes; j++ { wg.Add(1) @@ -96,7 +97,7 @@ func BenchmarkAntsPoolWithFunc(b *testing.B) { p.Serve(Param) } wg.Wait() - b.Logf("running goroutines: %d", p.Running()) + //b.Logf("running goroutines: %d", p.Running()) } } @@ -111,7 +112,6 @@ func BenchmarkGoroutine(b *testing.B) { func BenchmarkAntsPool(b *testing.B) { p, _ := ants.NewPoolWithFunc(AntsSize, demoPoolFunc) defer p.Release() - b.ResetTimer() for i := 0; i < b.N; i++ { for j := 0; j < RunTimes; j++ { diff --git a/ants_test.go b/ants_test.go index 3fb42a0..5fdc4af 100644 --- a/ants_test.go +++ b/ants_test.go @@ -28,7 +28,7 @@ import ( "testing" "time" - "github.com/panjf2000/ants" + "github.com/liyonglion/ants" ) var n = 100000 diff --git a/pool.go b/pool.go index 987ba4d..8fee19f 100644 --- a/pool.go +++ b/pool.go @@ -52,7 +52,7 @@ type Pool struct { // lock for synchronous operation. lock sync.Mutex - + cond *sync.Cond once sync.Once } @@ -105,6 +105,7 @@ func NewTimingPool(size, expiry int) (*Pool, error) { release: make(chan sig, 1), expiryDuration: time.Duration(expiry) * time.Second, } + p.cond = sync.NewCond(&p.lock) go p.periodicallyPurge() return p, nil } @@ -183,6 +184,7 @@ func (p *Pool) getWorker() *Worker { waiting := false p.lock.Lock() + defer p.lock.Unlock() idleWorkers := p.workers n := len(idleWorkers) - 1 if n < 0 { @@ -192,21 +194,17 @@ func (p *Pool) getWorker() *Worker { idleWorkers[n] = nil p.workers = idleWorkers[:n] } - p.lock.Unlock() if waiting { - for { - p.lock.Lock() - idleWorkers = p.workers - l := len(idleWorkers) - 1 - if l < 0 { - p.lock.Unlock() + for{ + p.cond.Wait() + l := len(p.workers) - 1 + if l < 0{ continue } - w = idleWorkers[l] - idleWorkers[l] = nil - p.workers = idleWorkers[:l] - p.lock.Unlock() + w = p.workers[l] + p.workers[l] = nil + p.workers = p.workers[:l] break } } else if w == nil { @@ -225,5 +223,7 @@ func (p *Pool) putWorker(worker *Worker) { worker.recycleTime = time.Now() p.lock.Lock() p.workers = append(p.workers, worker) + //通知有一个空闲的worker + p.cond.Signal() p.lock.Unlock() } diff --git a/pool_func.go b/pool_func.go index 6051117..f0c75e5 100644 --- a/pool_func.go +++ b/pool_func.go @@ -50,7 +50,7 @@ type PoolWithFunc struct { // lock for synchronous operation. lock sync.Mutex - + cond *sync.Cond // pf is the function for processing tasks. poolFunc pf @@ -107,6 +107,7 @@ func NewTimingPoolWithFunc(size, expiry int, f pf) (*PoolWithFunc, error) { expiryDuration: time.Duration(expiry) * time.Second, poolFunc: f, } + p.cond = sync.NewCond(&p.lock) go p.periodicallyPurge() return p, nil } @@ -185,6 +186,7 @@ func (p *PoolWithFunc) getWorker() *WorkerWithFunc { waiting := false p.lock.Lock() + defer p.lock.Unlock() idleWorkers := p.workers n := len(idleWorkers) - 1 if n < 0 { @@ -194,23 +196,20 @@ func (p *PoolWithFunc) getWorker() *WorkerWithFunc { idleWorkers[n] = nil p.workers = idleWorkers[:n] } - p.lock.Unlock() if waiting { - for { - p.lock.Lock() - idleWorkers = p.workers - l := len(idleWorkers) - 1 - if l < 0 { - p.lock.Unlock() + for{ + p.cond.Wait() + l := len(p.workers) - 1 + if l < 0{ continue } - w = idleWorkers[l] - idleWorkers[l] = nil - p.workers = idleWorkers[:l] - p.lock.Unlock() + w = p.workers[l] + p.workers[l] = nil + p.workers = p.workers[:l] break } + } else if w == nil { w = &WorkerWithFunc{ pool: p, @@ -227,5 +226,7 @@ func (p *PoolWithFunc) putWorker(worker *WorkerWithFunc) { worker.recycleTime = time.Now() p.lock.Lock() p.workers = append(p.workers, worker) + //通知有一个空闲的worker + p.cond.Signal() p.lock.Unlock() }