mirror of
https://gitee.com/johng/gf.git
synced 2024-12-01 03:38:35 +08:00
gtimer updates; grand updates, change buffer slice type from uint64 to uint32
This commit is contained in:
parent
14fcd0b2f9
commit
bf25a3a601
@ -20,6 +20,7 @@ import (
|
||||
const (
|
||||
STATUS_READY = 0
|
||||
STATUS_RUNNING = 1
|
||||
STATUS_STOPPED = 2
|
||||
STATUS_CLOSED = -1
|
||||
gPANIC_EXIT = "exit"
|
||||
gDEFAULT_TIMES = math.MaxInt32
|
||||
|
@ -16,12 +16,11 @@ type Entry struct {
|
||||
job JobFunc // 注册循环任务方法
|
||||
wheel *wheel // 所属时间轮
|
||||
singleton *gtype.Bool // 任务是否单例运行
|
||||
status *gtype.Int // 任务状态(0: ready; 1: running; -1: closed)
|
||||
status *gtype.Int // 任务状态(0: ready; 1: running; 2: stopped; -1: closed)
|
||||
times *gtype.Int // 还需运行次数
|
||||
create int64 // 注册时的时间轮ticks
|
||||
interval int64 // 设置的运行间隔(时间轮刻度数量)
|
||||
createMs int64 // 创建时间(毫秒)
|
||||
updateMs int64 // 更新时间(上一次检查/运行时间, 毫秒)
|
||||
intervalMs int64 // 间隔时间(毫秒)
|
||||
}
|
||||
|
||||
@ -48,7 +47,6 @@ func (w *wheel) addEntry(interval time.Duration, job JobFunc, singleton bool, ti
|
||||
create : ticks,
|
||||
interval : num,
|
||||
createMs : nowMs,
|
||||
updateMs : nowMs,
|
||||
intervalMs : ms,
|
||||
}
|
||||
// 安装任务
|
||||
@ -56,14 +54,13 @@ func (w *wheel) addEntry(interval time.Duration, job JobFunc, singleton bool, ti
|
||||
return entry
|
||||
}
|
||||
|
||||
// 递增添加任务
|
||||
// 重新添加任务
|
||||
func (w *wheel) reAddEntry(entry *Entry, nowTicks int64, nowMs int64) {
|
||||
left := entry.interval - (nowTicks - entry.create)
|
||||
if left <= 0 {
|
||||
left = entry.interval
|
||||
entry.create = nowTicks
|
||||
entry.createMs = nowMs
|
||||
entry.updateMs = nowMs
|
||||
}
|
||||
w.slots[(nowTicks + left) % w.number].PushBack(entry)
|
||||
}
|
||||
@ -78,6 +75,16 @@ func (entry *Entry) SetStatus(status int) int {
|
||||
return entry.status.Set(status)
|
||||
}
|
||||
|
||||
// 启动当前任务
|
||||
func (entry *Entry) Start() {
|
||||
entry.status.Set(STATUS_READY)
|
||||
}
|
||||
|
||||
// 停止当前任务
|
||||
func (entry *Entry) Stop() {
|
||||
entry.status.Set(STATUS_STOPPED)
|
||||
}
|
||||
|
||||
// 关闭当前任务
|
||||
func (entry *Entry) Close() {
|
||||
entry.status.Set(STATUS_CLOSED)
|
||||
@ -105,6 +112,10 @@ func (entry *Entry) Run() {
|
||||
|
||||
// 检测当前任务是否可运行, 参数为当前时间的纳秒数, 精度更高
|
||||
func (entry *Entry) check(nowTicks int64, nowMs int64) bool {
|
||||
// 是否停止
|
||||
if entry.status.Val() == STATUS_STOPPED {
|
||||
return false
|
||||
}
|
||||
// 运行检查
|
||||
if diff := nowTicks - entry.create; diff > 0 && diff%entry.interval == 0 {
|
||||
// 是否单例
|
||||
@ -126,16 +137,18 @@ func (entry *Entry) check(nowTicks int64, nowMs int64) bool {
|
||||
times = gDEFAULT_TIMES
|
||||
entry.times.Set(gDEFAULT_TIMES)
|
||||
}
|
||||
// 分层转换
|
||||
// 分层转换处理
|
||||
if entry.wheel.level > 0 {
|
||||
if diffMs := nowMs - entry.updateMs; diffMs < entry.intervalMs {
|
||||
if leftMs := entry.intervalMs - diffMs; leftMs > entry.wheel.wheels.intervalMs {
|
||||
// 是否达到任务运行间隔
|
||||
if diffMs := nowMs - entry.createMs; diffMs < entry.intervalMs {
|
||||
// 任务是否有必要进行分层转换
|
||||
if leftMs := entry.intervalMs - diffMs; leftMs > entry.wheel.timer.intervalMs {
|
||||
delay := time.Duration(leftMs)*time.Millisecond
|
||||
// 往底层添加
|
||||
entry.wheel.wheels.addEntry(delay, entry.job, false, 1)
|
||||
entry.wheel.timer.addEntry(delay, entry.job, false, 1)
|
||||
// 延迟重新添加
|
||||
if times > 0 {
|
||||
entry.wheel.wheels.DelayAddTimes(
|
||||
entry.wheel.timer.DelayAddTimes(
|
||||
delay,
|
||||
time.Duration(entry.intervalMs)*time.Millisecond,
|
||||
times,
|
||||
|
@ -17,12 +17,17 @@ func (w *wheel) start() {
|
||||
ticker := time.NewTicker(time.Duration(w.intervalMs)*time.Millisecond)
|
||||
for {
|
||||
select {
|
||||
case <- w.closed:
|
||||
case <- ticker.C:
|
||||
switch w.timer.status.Val() {
|
||||
case STATUS_READY: fallthrough
|
||||
case STATUS_RUNNING:
|
||||
w.proceed()
|
||||
case STATUS_STOPPED:
|
||||
case STATUS_CLOSED:
|
||||
ticker.Stop()
|
||||
return
|
||||
}
|
||||
|
||||
case <- ticker.C:
|
||||
w.proceed()
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
@ -14,6 +14,7 @@ import (
|
||||
|
||||
// 定时器/分层时间轮
|
||||
type Timer struct {
|
||||
status *gtype.Int // 状态
|
||||
wheels []*wheel // 分层
|
||||
length int // 层数
|
||||
number int // 每一层Slot Number
|
||||
@ -27,6 +28,7 @@ func New(slot int, interval time.Duration, level...int) *Timer {
|
||||
length = level[0]
|
||||
}
|
||||
t := &Timer {
|
||||
status : gtype.NewInt(STATUS_RUNNING),
|
||||
wheels : make([]*wheel, length),
|
||||
length : length,
|
||||
number : slot,
|
||||
@ -49,11 +51,10 @@ func New(slot int, interval time.Duration, level...int) *Timer {
|
||||
// 创建自定义的循环任务管理对象
|
||||
func (t *Timer) newWheel(level int, slot int, interval time.Duration) *wheel {
|
||||
w := &wheel {
|
||||
wheels : t,
|
||||
timer : t,
|
||||
level : level,
|
||||
slots : make([]*glist.List, slot),
|
||||
number : int64(slot),
|
||||
closed : make(chan struct{}, 1),
|
||||
ticks : gtype.NewInt64(),
|
||||
totalMs : int64(slot)*interval.Nanoseconds()/1e6,
|
||||
createMs : time.Now().UnixNano()/1e6,
|
||||
@ -113,11 +114,19 @@ func (t *Timer) DelayAddTimes(delay time.Duration, interval time.Duration, times
|
||||
})
|
||||
}
|
||||
|
||||
// 关闭分层时间轮
|
||||
func (t *Timer) Close() {
|
||||
for _, w := range t.wheels {
|
||||
w.Close()
|
||||
// 启动定时器
|
||||
func (t *Timer) Start() {
|
||||
t.status.Set(STATUS_RUNNING)
|
||||
}
|
||||
|
||||
// 定制定时器
|
||||
func (t *Timer) Stop() {
|
||||
t.status.Set(STATUS_STOPPED)
|
||||
}
|
||||
|
||||
// 关闭定时器
|
||||
func (t *Timer) Close() {
|
||||
t.status.Set(STATUS_CLOSED)
|
||||
}
|
||||
|
||||
// 添加定时任务
|
||||
|
@ -13,18 +13,12 @@ import (
|
||||
|
||||
// 单层时间轮
|
||||
type wheel struct {
|
||||
wheels *Timer // 所属定时器
|
||||
timer *Timer // 所属定时器
|
||||
level int // 所属分层索引号
|
||||
slots []*glist.List // 所有的循环任务项, 按照Slot Number进行分组
|
||||
number int64 // Slot Number
|
||||
closed chan struct{} // 停止事件
|
||||
ticks *gtype.Int64 // 当前时间轮已转动的刻度数量
|
||||
totalMs int64 // 整个时间轮的时间长度(毫秒)=number*interval
|
||||
createMs int64 // 创建时间(毫秒)
|
||||
intervalMs int64 // 时间间隔(slot时间长度, 毫秒)
|
||||
}
|
||||
|
||||
// 关闭循环任务
|
||||
func (w *wheel) Close() {
|
||||
w.closed <- struct{}{}
|
||||
}
|
@ -12,12 +12,20 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
|
||||
var (
|
||||
timer = gtimer.New(5, 30*time.Millisecond)
|
||||
)
|
||||
func Benchmark_Add(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
// 基准测试的时候不能设置为1秒,否则大量的任务会崩掉系统
|
||||
gtimer.Add(time.Hour, func() {
|
||||
timer.Add(time.Hour, func() {
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Benchmark_StartStop(b *testing.B) {
|
||||
for i := 0; i < b.N; i++ {
|
||||
timer.Start()
|
||||
timer.Stop()
|
||||
}
|
||||
}
|
||||
|
@ -23,9 +23,15 @@ func TestTimer_Entry_Operation(t *testing.T) {
|
||||
})
|
||||
time.Sleep(1200*time.Millisecond)
|
||||
gtest.Assert(array.Len(), 1)
|
||||
entry.Close()
|
||||
entry.Stop()
|
||||
time.Sleep(1200*time.Millisecond)
|
||||
gtest.Assert(array.Len(), 1)
|
||||
entry.Start()
|
||||
time.Sleep(1200*time.Millisecond)
|
||||
gtest.Assert(array.Len(), 2)
|
||||
entry.Close()
|
||||
time.Sleep(1200*time.Millisecond)
|
||||
gtest.Assert(array.Len(), 2)
|
||||
}
|
||||
|
||||
func TestTimer_Entry_Singleton(t *testing.T) {
|
||||
|
@ -12,11 +12,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
gBUFFER_SIZE = 10000 // 缓冲区uint64数量大小
|
||||
gBUFFER_SIZE = 10000 // 缓冲区uint32数量大小
|
||||
)
|
||||
|
||||
var (
|
||||
bufferChan = make(chan uint64, gBUFFER_SIZE)
|
||||
bufferChan = make(chan uint32, gBUFFER_SIZE)
|
||||
)
|
||||
|
||||
// 使用缓冲区实现快速的随机数生成
|
||||
@ -29,14 +29,14 @@ func init() {
|
||||
panic(err)
|
||||
} else {
|
||||
// 使用缓冲区数据进行一次完整的随机数生成
|
||||
for i := 0; i < n - 8; {
|
||||
bufferChan <- binary.LittleEndian.Uint64(buffer[i : i + 8])
|
||||
for i := 0; i < n - 4; {
|
||||
bufferChan <- binary.LittleEndian.Uint32(buffer[i : i + 4])
|
||||
i ++
|
||||
}
|
||||
// 充分利用缓冲区数据,随机索引递增
|
||||
step = int(buffer[0])%10
|
||||
for i := 0; i < n - 8; {
|
||||
bufferChan <- binary.BigEndian.Uint64(buffer[i : i + 8])
|
||||
for i := 0; i < n - 4; {
|
||||
bufferChan <- binary.BigEndian.Uint32(buffer[i : i + 4])
|
||||
i += step
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
|
||||
func main() {
|
||||
now := time.Now()
|
||||
interval := 1000*time.Millisecond
|
||||
interval := 1400*time.Millisecond
|
||||
gtimer.Add(interval, func() {
|
||||
fmt.Println(time.Now(), time.Duration(time.Now().UnixNano() - now.UnixNano()))
|
||||
now = time.Now()
|
||||
|
Loading…
Reference in New Issue
Block a user