From 339aaa44752f9ffd7679720ce8f14fa5a770408a Mon Sep 17 00:00:00 2001 From: Andy Pan Date: Fri, 6 Jul 2018 20:20:18 +0800 Subject: [PATCH 1/3] update --- pool.go | 3 ++- pool_func.go | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pool.go b/pool.go index 9184c24..38fe397 100644 --- a/pool.go +++ b/pool.go @@ -76,9 +76,10 @@ func (p *Pool) monitorAndClear() { n = i w.stop() idleWorkers[i] = nil + p.running-- } if n > 0 { - n += 1 + n++ p.workers = idleWorkers[n:] } p.lock.Unlock() diff --git a/pool_func.go b/pool_func.go index 439b0fe..485ebe1 100644 --- a/pool_func.go +++ b/pool_func.go @@ -77,6 +77,7 @@ func (p *PoolWithFunc) MonitorAndClear() { n = i w.stop() idleWorkers[i] = nil + p.running-- } if n > 0 { n += 1 From 6da1112dffab68138ea08a1b029f3d274a9ba8e8 Mon Sep 17 00:00:00 2001 From: Andy Pan Date: Fri, 6 Jul 2018 20:24:47 +0800 Subject: [PATCH 2/3] gofmt --- ants.go | 1 - ants_benchmark_test.go | 18 +++++++++--------- examples/main.go | 2 +- pool.go | 9 ++++----- pool_func.go | 10 +++++----- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/ants.go b/ants.go index 78e3b63..adfaed8 100644 --- a/ants.go +++ b/ants.go @@ -68,4 +68,3 @@ var ( ErrPoolSizeInvalid = errors.New("invalid size for pool") ErrPoolClosed = errors.New("this pool has been closed") ) - diff --git a/ants_benchmark_test.go b/ants_benchmark_test.go index 35c83a3..ffff333 100644 --- a/ants_benchmark_test.go +++ b/ants_benchmark_test.go @@ -32,14 +32,14 @@ import ( const ( _ = 1 << (10 * iota) - KiB // 1024 - MiB // 1048576 - GiB // 1073741824 - TiB // 1099511627776 (超过了int32的范围) - PiB // 1125899906842624 - EiB // 1152921504606846976 - ZiB // 1180591620717411303424 (超过了int64的范围) - YiB // 1208925819614629174706176 + KiB // 1024 + MiB // 1048576 + GiB // 1073741824 + TiB // 1099511627776 (超过了int32的范围) + PiB // 1125899906842624 + EiB // 1152921504606846976 + ZiB // 1180591620717411303424 (超过了int64的范围) + YiB // 1208925819614629174706176 ) const RunTimes = 1000000 const loop = 10 @@ -78,7 +78,7 @@ func BenchmarkGoroutineWithFunc(b *testing.B) { func BenchmarkAntsPoolWithFunc(b *testing.B) { var wg sync.WaitGroup - p, _ := ants.NewPoolWithFunc(50000, 1,func(i interface{}) error { + p, _ := ants.NewPoolWithFunc(50000, 1, func(i interface{}) error { demoPoolFunc(i) wg.Done() return nil diff --git a/examples/main.go b/examples/main.go index c9b6aae..f39861e 100644 --- a/examples/main.go +++ b/examples/main.go @@ -51,7 +51,7 @@ func main() { runTimes := 1000 - // use the common pool + // use the common pool var wg sync.WaitGroup for i := 0; i < runTimes; i++ { wg.Add(1) diff --git a/pool.go b/pool.go index 38fe397..8eda8d3 100644 --- a/pool.go +++ b/pool.go @@ -87,16 +87,15 @@ func (p *Pool) monitorAndClear() { }() } - // NewPool generates a instance of ants pool func NewPool(size, expiry int) (*Pool, error) { if size <= 0 { return nil, ErrPoolSizeInvalid } p := &Pool{ - capacity: int32(size), - freeSignal: make(chan sig, math.MaxInt32), - release: make(chan sig, 1), + capacity: int32(size), + freeSignal: make(chan sig, math.MaxInt32), + release: make(chan sig, 1), expiryDuration: time.Duration(expiry) * time.Second, } p.monitorAndClear() @@ -138,7 +137,7 @@ func (p *Pool) Release() error { for i := 0; i < running; i++ { p.getWorker().stop() } - for i := range p.workers{ + for i := range p.workers { p.workers[i] = nil } }) diff --git a/pool_func.go b/pool_func.go index 485ebe1..52e3515 100644 --- a/pool_func.go +++ b/pool_func.go @@ -94,11 +94,11 @@ func NewPoolWithFunc(size, expiry int, f pf) (*PoolWithFunc, error) { return nil, ErrPoolSizeInvalid } p := &PoolWithFunc{ - capacity: int32(size), - freeSignal: make(chan sig, math.MaxInt32), - release: make(chan sig, 1), + capacity: int32(size), + freeSignal: make(chan sig, math.MaxInt32), + release: make(chan sig, 1), expiryDuration: time.Duration(expiry) * time.Second, - poolFunc: f, + poolFunc: f, } p.MonitorAndClear() return p, nil @@ -142,7 +142,7 @@ func (p *PoolWithFunc) Release() error { for i := 0; i < running; i++ { p.getWorker().stop() } - for i := range p.workers{ + for i := range p.workers { p.workers[i] = nil } }) From a2fbed190067283dc8b01bfc9808ca016c7d2821 Mon Sep 17 00:00:00 2001 From: Andy Pan Date: Fri, 6 Jul 2018 20:39:23 +0800 Subject: [PATCH 3/3] update example codes --- README.md | 14 +++++++++++--- README_ZH.md | 7 ++++--- examples/main.go | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 341c21b..ab6a6ce 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,6 @@ glide get github.com/panjf2000/ants If your program will generate a massive number of goroutines and you don't want them to consume a vast amount of memory, with ants, all you need to do is to import ants package and submit all your tasks to the default limited pool created when ants was imported: ``` go - package main import ( @@ -84,8 +83,8 @@ func main() { fmt.Printf("finish all tasks.\n") // use the pool with a function - // set 10 the size of goroutine pool - p, _ := ants.NewPoolWithFunc(10, func(i interface{}) error { + // set 10 the size of goroutine pool and 1 second for expired duration + p, _ := ants.NewPoolWithFunc(10, 1, func(i interface{}) error { myFunc(i) wg.Done() return nil @@ -132,6 +131,15 @@ Don't worry about the synchronous problems in this case, this method is thread-s All the tasks submitted to ants pool will not be guaranteed to be processed in order, because those tasks distribute among a series of concurrent workers, thus those tasks are processed concurrently. ## Benchmarks + +``` +OS : macOS High Sierra +Processor : 2.7 GHz Intel Core i5 +Memory : 8 GB 1867 MHz DDR3 + +Go1.9 +``` +
In that benchmark-picture, the first and second benchmarks performed test with 100w tasks and the rest of benchmarks performed test with 1000w tasks, both unlimited goroutines and ants pool, and the capacity of this ants goroutine-pool was limited to 5w. diff --git a/README_ZH.md b/README_ZH.md index 245db02..8a61528 100644 --- a/README_ZH.md +++ b/README_ZH.md @@ -38,7 +38,6 @@ glide get github.com/panjf2000/ants 写 go 并发程序的时候如果程序会启动大量的 goroutine ,势必会消耗大量的系统资源(内存,CPU),通过使用 `ants`,可以实例化一个协程池,复用 goroutine ,节省资源,提升性能: ``` go - package main import ( @@ -85,8 +84,8 @@ func main() { fmt.Printf("finish all tasks.\n") // use the pool with a function - // set 10 the size of goroutine pool - p, _ := ants.NewPoolWithFunc(10, func(i interface{}) error { + // set 10 the size of goroutine pool and 1 second for expired duration + p, _ := ants.NewPoolWithFunc(10, 1, func(i interface{}) error { myFunc(i) wg.Done() return nil @@ -137,6 +136,8 @@ pool.ReSize(100000) // Readjust its capacity to 100000 OS : macOS High Sierra Processor : 2.7 GHz Intel Core i5 Memory : 8 GB 1867 MHz DDR3 + +Go1.9 ``` diff --git a/examples/main.go b/examples/main.go index f39861e..5a30c56 100644 --- a/examples/main.go +++ b/examples/main.go @@ -66,7 +66,7 @@ func main() { fmt.Printf("finish all tasks.\n") // use the pool with a function - // set 10 the size of goroutine pool + // set 10 the size of goroutine pool and 1 second for expired duration p, _ := ants.NewPoolWithFunc(10, 1, func(i interface{}) error { myFunc(i) wg.Done()