Commit 1991056b authored by AlexStocks's avatar AlexStocks

Imp: task pool worker_number/chan_number is M:N

parent 79f3f666
...@@ -3,6 +3,11 @@ package getty ...@@ -3,6 +3,11 @@ package getty
import ( import (
"fmt" "fmt"
"sync" "sync"
"sync/atomic"
)
const (
defaultTaskQNumber = 10
) )
// task t // task t
...@@ -13,10 +18,11 @@ type task struct { ...@@ -13,10 +18,11 @@ type task struct {
// task pool: manage task ts // task pool: manage task ts
type taskPool struct { type taskPool struct {
qLen int32 // task queue length idx uint32
size int32 // task queue pool size qLen int32 // task queue length
Q chan task size int32 // task queue pool size
wg sync.WaitGroup qArray []chan task
wg sync.WaitGroup
once sync.Once once sync.Once
done chan struct{} done chan struct{}
...@@ -24,12 +30,18 @@ type taskPool struct { ...@@ -24,12 +30,18 @@ type taskPool struct {
// build a task pool // build a task pool
func newTaskPool(poolSize int32, taskQLen int32) *taskPool { func newTaskPool(poolSize int32, taskQLen int32) *taskPool {
return &taskPool{ p := &taskPool{
size: poolSize, size: poolSize,
qLen: taskQLen, qLen: taskQLen,
Q: make(chan task, taskQLen), qArray: make([]chan task, defaultTaskQNumber),
done: make(chan struct{}), done: make(chan struct{}),
}
for i := 0; i < defaultTaskQNumber; i++ {
p.qArray[i] = make(chan task, taskQLen)
} }
return p
} }
// start task pool // start task pool
...@@ -44,13 +56,14 @@ func (p *taskPool) start() { ...@@ -44,13 +56,14 @@ func (p *taskPool) start() {
for i := int32(0); i < p.size; i++ { for i := int32(0); i < p.size; i++ {
p.wg.Add(1) p.wg.Add(1)
taskID := i workerID := i
go p.run(int(taskID)) q := p.qArray[workerID%defaultTaskQNumber]
go p.run(int(workerID), q)
} }
} }
// worker // worker
func (p *taskPool) run(id int) { func (p *taskPool) run(id int, q chan task) {
defer p.wg.Done() defer p.wg.Done()
var ( var (
...@@ -61,15 +74,15 @@ func (p *taskPool) run(id int) { ...@@ -61,15 +74,15 @@ func (p *taskPool) run(id int) {
for { for {
select { select {
case <-p.done: case <-p.done:
if 0 < len(p.Q) { if 0 < len(q) {
log.Warn("[getty][task_pool] task worker %d exit now while its task buffer length %d is greater than 0", log.Warn("[getty][task_pool] task worker %d exit now while its task buffer length %d is greater than 0",
id, len(p.Q)) id, len(q))
} else { } else {
log.Info("[getty][task_pool] task worker %d exit now", id) log.Info("[getty][task_pool] task worker %d exit now", id)
} }
return return
case t, ok = <-p.Q: case t, ok = <-q:
if ok { if ok {
t.session.listener.OnMessage(t.session, t.pkg) t.session.listener.OnMessage(t.session, t.pkg)
} }
...@@ -79,10 +92,12 @@ func (p *taskPool) run(id int) { ...@@ -79,10 +92,12 @@ func (p *taskPool) run(id int) {
// add task // add task
func (p *taskPool) AddTask(t task) { func (p *taskPool) AddTask(t task) {
id := atomic.AddUint32(&p.idx, 1) % defaultTaskQNumber
select { select {
case <-p.done: case <-p.done:
return return
case p.Q <- t: case p.qArray[id] <- t:
} }
} }
...@@ -112,5 +127,7 @@ func (p *taskPool) isClosed() bool { ...@@ -112,5 +127,7 @@ func (p *taskPool) isClosed() bool {
func (p *taskPool) close() { func (p *taskPool) close() {
p.stop() p.stop()
p.wg.Wait() p.wg.Wait()
close(p.Q) for i := range p.qArray {
close(p.qArray[i])
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment