Merge branch 'master' into develop

This commit is contained in:
Andy Pan 2018-09-29 19:46:29 +08:00
commit 6366d137ea
5 changed files with 31 additions and 30 deletions

View File

@ -182,9 +182,9 @@ There was only the test of `ants` Pool because my computer was crash when it rea
**As you can see, `ants` can up to 2x~6x faster than goroutines without pool and the memory consumption is reduced by 10 to 20 times.**
[1]: https://travis-ci.com/panjf2000/ants.svg?branch=develop
[1]: https://travis-ci.com/panjf2000/ants.svg?branch=master
[2]: https://travis-ci.com/panjf2000/ants
[3]: https://codecov.io/gh/panjf2000/ants/branch/develop/graph/badge.svg
[3]: https://codecov.io/gh/panjf2000/ants/branch/master/graph/badge.svg
[4]: https://codecov.io/gh/panjf2000/ants
[5]: https://goreportcard.com/badge/github.com/panjf2000/ants
[6]: https://goreportcard.com/report/github.com/panjf2000/ants

View File

@ -180,9 +180,9 @@ Go1.9
**从该demo测试吞吐性能对比可以看出使用ants的吞吐性能相较于原生goroutine可以保持在2-6倍的性能压制而内存消耗则可以达到10-20倍的节省优势。**
[1]: https://travis-ci.com/panjf2000/ants.svg?branch=develop
[1]: https://travis-ci.com/panjf2000/ants.svg?branch=master
[2]: https://travis-ci.com/panjf2000/ants
[3]: https://codecov.io/gh/panjf2000/ants/branch/develop/graph/badge.svg
[3]: https://codecov.io/gh/panjf2000/ants/branch/master/graph/badge.svg
[4]: https://codecov.io/gh/panjf2000/ants
[5]: https://goreportcard.com/badge/github.com/panjf2000/ants
[6]: https://goreportcard.com/report/github.com/panjf2000/ants

View File

@ -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++ {

24
pool.go
View File

@ -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()
}

View File

@ -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()
}