From f80b199d24ff9aef04541373a2630e57033579f5 Mon Sep 17 00:00:00 2001 From: John Date: Mon, 15 Jan 2018 22:42:58 +0800 Subject: [PATCH] =?UTF-8?q?groutine=E6=80=A7=E8=83=BD=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- g/os/groutine/groutine.go | 20 +++++++++++++++++--- g/os/groutine/groutine_api.go | 12 ++++++++---- g/os/groutine/groutine_job.go | 2 ++ g/os/groutine/groutine_test.go | 31 +++++++++++++++++++++++++++++++ geg/other/test.go | 13 ++++++++++++- 5 files changed, 70 insertions(+), 8 deletions(-) create mode 100644 g/os/groutine/groutine_test.go diff --git a/g/os/groutine/groutine.go b/g/os/groutine/groutine.go index 5a1843e60..f3c39d087 100644 --- a/g/os/groutine/groutine.go +++ b/g/os/groutine/groutine.go @@ -15,8 +15,9 @@ import ( // goroutine池对象 type Pool struct { - queue *glist.SafeList // 空闲任务队列*PoolJob) - pjobs *gset.InterfaceSet // 当前任务对象(*PoolJob) + jobs *gset.InterfaceSet // 当前任务对象(*PoolJob) + queue *glist.SafeList // 空闲任务队列(*PoolJob) + funcs []chan func() // 待处理任务操作 } // goroutine任务 @@ -26,6 +27,19 @@ type PoolJob struct { pool *Pool // 所属池 } +// 任务分配循环 +func (p *Pool) loop() { + go func() { + for { + if f := <- p.funcs; f != nil { + p.getJob().setJob(f) + } else { + return + } + } + }() +} + // 创建一个空的任务对象 func (p *Pool) newJob() *PoolJob { j := &PoolJob { @@ -33,7 +47,7 @@ func (p *Pool) newJob() *PoolJob { pool : p, } j.start() - p.pjobs.Add(j) + p.jobs.Add(j) return j } diff --git a/g/os/groutine/groutine_api.go b/g/os/groutine/groutine_api.go index ea24960a9..e116c2e5c 100644 --- a/g/os/groutine/groutine_api.go +++ b/g/os/groutine/groutine_api.go @@ -13,20 +13,24 @@ import ( // 创建goroutine池管理对象 func New() *Pool { - return &Pool { + p := &Pool { + jobs : gset.NewInterfaceSet(), queue : glist.NewSafeList(), - pjobs : gset.NewInterfaceSet(), + funcs : make(chan func(), 1000000), } + p.loop() + return p } // 添加异步任务 func (p *Pool) Add(f func()) { - p.getJob().setJob(f) + p.funcs <- f } // 关闭池,所有的任务将会停止,此后继续添加的任务将不会被执行 func (p *Pool) Close() { - p.pjobs.Iterator(func(v interface{}){ + p.funcs <- nil + p.jobs.Iterator(func(v interface{}){ v.(*PoolJob).stop() }) } \ No newline at end of file diff --git a/g/os/groutine/groutine_job.go b/g/os/groutine/groutine_job.go index 8629c4b7f..71ea8a117 100644 --- a/g/os/groutine/groutine_job.go +++ b/g/os/groutine/groutine_job.go @@ -13,6 +13,8 @@ func (j *PoolJob) start() { if f := <- j.job; f != nil { // 执行任务 f() + // 清空任务(GC可回收f对应资源) + j.job = nil // 执行完毕后添加到空闲队列 j.pool.addJob(j) } else { diff --git a/g/os/groutine/groutine_test.go b/g/os/groutine/groutine_test.go new file mode 100644 index 000000000..2258d7a9b --- /dev/null +++ b/g/os/groutine/groutine_test.go @@ -0,0 +1,31 @@ +package groutine_test + +import ( + "testing" + "gitee.com/johng/gf/g/os/groutine" +) + +func test() { + num := 0 + for i := 0; i < 1000000; i++ { + num += i + } +} + +var pool = groutine.New() + +func BenchmarkGroutine(b *testing.B) { + for i := 0; i < b.N; i++ { + pool.Add(test) + } + //pool.Close() +} + +//func BenchmarkGoRoutine(b *testing.B) { +// t := gtime.Microsecond() +// b.N = 100000 +// for i := 0; i < b.N; i++ { +// go test() +// } +// fmt.Println("BenchmarkGoRoutine costs:", gtime.Microsecond() - t) +//} \ No newline at end of file diff --git a/geg/other/test.go b/geg/other/test.go index 35397ac8e..b22f57484 100644 --- a/geg/other/test.go +++ b/geg/other/test.go @@ -1,9 +1,20 @@ package main import ( + "gitee.com/johng/gf/g/os/gtime" "fmt" + "gitee.com/johng/gf/g/container/glist" ) func main() { - fmt.Println(len(make(chan int, 10))) + + t1 := gtime.Microsecond() + c := make(chan func(), 10) + c <- func(){} + fmt.Println(gtime.Microsecond() - t1) + + t2 := gtime.Microsecond() + l := glist.NewSafeList() + l.PushBack(func() {}) + fmt.Println(gtime.Microsecond() - t2) } \ No newline at end of file