基于简单时间轮的定时任务功能

文章介绍了一个使用Go语言实现的基于简单时间轮的定时任务系统,该系统利用原子操作更新当前时间,并在每个时间槽检查是否有任务需要执行。同时提到了其他系统如Nginx和Linux内核中定时任务的数据结构,如红黑树和小顶堆。
摘要由CSDN通过智能技术生成

定时任务

定时任务底层涉及到的数据结构与算法有很多种,如
nginx:红黑树,Go:小顶堆,Linux内核:时间轮

时间轮可以分为简单时间轮和层级时间轮,如下粗糙的实现了基于简单时间轮的定时任务功能。

package main

import (
	"fmt"
	"sync/atomic"
	"time"
)

const SECONDS = 60

type task []struct {
	stop   bool
	doTime uint32
	do     func()
}

type Timer struct {
	seconds     [SECONDS]task
	currentTime uint32
}

func NewTimer() *Timer {

	t := &Timer{
		seconds:     [60]task{},
		currentTime: 0,
	}
	go func() {
		for {
			for i := 0; i < 5; i++ {
				time.Sleep(time.Millisecond * 200)
			}
			atomic.StoreUint32(&t.currentTime, atomic.AddUint32(&t.currentTime, +1))
		}
	}()

	go func() {
		for {
			index := atomic.LoadUint32(&t.currentTime) % SECONDS
			tasks := t.seconds[index]
			for idx := range tasks {
				if tasks[idx].stop == false && tasks[idx].doTime <= atomic.LoadUint32(&t.currentTime) {
					tasks[idx].stop = true
					go tasks[idx].do()
				}
			}
			
			for i := 0; i < 3; i++ {
				time.Sleep(time.Millisecond * 200)
			}
		}
	}()
	return t
}

func (t *Timer) AfterFunc(second uint32, fn func()) {
	index := atomic.LoadUint32(&t.currentTime) + second
	t.seconds[index%SECONDS] = append(t.seconds[index%SECONDS], struct {
		stop   bool
		doTime uint32
		do     func()
	}{stop: false, doTime: index, do: fn})
}

func main() {
	t := NewTimer()

	t.AfterFunc(5, func() {
		fmt.Println("hello world")
	})

	t.AfterFunc(60, func() {
		fmt.Println("hello world1")
	})

	t.AfterFunc(10, func() {
		fmt.Println("hello 10s")
	})

	time.Sleep(time.Second * 100)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

metabit

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值