go语言重写c++ 游戏框架skynet 的时间轮

项目地址:

https://github.com/gorustyt/timerWheel

游戏中的定时器一般是两种

  • 一种是玩家所在线程调用update ,去处理过期的定时任务,通常由小顶堆实现
  • 另一种是全局定时器,该定时器执行过期任务的时候会另起一个线程,该线会和玩家的线程产生资源竞争,所以执行时候需要加锁。

skynet 时间轮的实现原理:

  • near 存储最近触发的定时器,有1<<8个链表维护
  • t 存储后续触发的定时器,共4层,每层由64个链表维护
  • 每次tick 会将near 的定时器进行触发,然后将后面4层的定时器往前移动

异步定时器,单独协程驱动:

package main

import (
	"fmt"
	tm "github.com/gorustyt/timerWheel"
	"time"
)

func main() {
	t := tm.NewAsyncTimeWheel()
	t.Schedule(1*time.Second, 1*time.Second, func(ts time.Time) {
		fmt.Println(time.Now())
	})
	time.Sleep(1000 * time.Second)
}
//result
timeWheel run start
2024-01-14 23:14:23.6401488 +0800 CST m=+1.005890901
2024-01-14 23:14:24.6424991 +0800 CST m=+2.008241201
2024-01-14 23:14:25.6376216 +0800 CST m=+3.003363701
2024-01-14 23:14:26.6455683 +0800 CST m=+4.011310401
2024-01-14 23:14:27.6367333 +0800 CST m=+5.002475401

同步定时器,调用协程自己驱动:

package main

import (
	"fmt"
	tm "github.com/gorustyt/timerWheel"
	"time"
)

func main() {
	//创建一个同步timer,需要自己驱动,调用update
	t := tm.NewSyncTimeWheel()

	//调度任务
	t.Schedule(1*time.Second, 1*time.Second, func(ts time.Time) {
		fmt.Println("Schedule=======", ts)
	})
	for { //驱动timer
		t.Update(time.Now(), func(ts time.Time, node *tm.TimerWheelNode) {
			fmt.Printf("manulal exec node id :%v\n", node.Id)
			node.Handle(ts)
		})
		time.Sleep(10 * time.Millisecond)
	}
}
  • 8
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值