zoukankan      html  css  js  c++  java
  • 计时器 海量定时/延迟任务

    6.11 计时器 | Go 语言原本 https://golang.design/under-the-hood/zh-cn/part2runtime/ch06sched/timer/

    https://mp.weixin.qq.com/s/tkm9nYcyUxE2vUbplSO-pA

    Go-Zero如何应对海量定时/延迟任务
    原创 hxl@好未来 GoCN 2020-10-10
    一个系统中存在着大量的调度任务,同时调度任务存在时间的滞后性,而大量的调度任务如果每一个都使用自己的调度器来管理任务的生命周期的话,浪费 cpu 的资源而且很低效。

    本文来介绍 go-zero 中 延迟操作,它可能让开发者调度多个任务时,只需关注具体的业务执行函数和执行时间「立即或者延迟」。而 延迟操作,通常可以采用两个方案:

    Timer:定时器维护一个优先队列,到时间点执行,然后把需要执行的 task 存储在 map 中

    collection 中的 timingWheel ,维护一个存放任务组的数组,每一个槽都维护一个存储 task 的双向链表。开始执行时,计时器每隔指定时间执行一个槽里面的 tasks。

    方案 2 把维护 task 从 优先队列 O(nlog(n)) 降到 双向链表 O(1),而执行 task 也只要轮询一个时间点的 tasks O(N),不需要像优先队列,放入和删除元素 O(nlog(n))。

    我们先看看 go-zero 中自己对 timingWheel 的使用 :

    // 2021/3/29 22:17 Shawn
    package main

    import (
    "fmt"
    "time"
    )

    func NOW() time.Time {
    return time.Now()
    }
    func t() int {
    fmt.Println("in-", NOW())
    go func() {
    fmt.Println("1-NewTimer", NOW())
    i := 60
    s := time.Duration(i) * time.Second
    timer := time.NewTimer(s)
    <-timer.C
    fmt.Println("2-NewTimer", NOW())

    }()
    fmt.Println("leave", NOW())
    return 123
    }
    func main() {
    i := t()
    fmt.Println("i=", i, NOW())
    for {

    }
    }

    in- 2021-07-09 16:18:09.3988014 +0800 CST m=+0.003173901
    leave 2021-07-09 16:18:09.4144284 +0800 CST m=+0.018800901
    i= 123 2021-07-09 16:18:09.4144284 +0800 CST m=+0.018800901
    1-NewTimer 2021-07-09 16:18:09.4144284 +0800 CST m=+0.018800901
    2-NewTimer 2021-07-09 16:19:09.4144658 +0800 CST m=+60.018838301

    package main

    import (
    "fmt"
    "time"
    )

    func NOW() time.Time {
    return time.Now()
    }
    func t() int {
    fmt.Println("in-", NOW())
    go func() {
    fmt.Println("1-NewTimer", NOW())
    i := 60
    s := time.Duration(i) * time.Second
    timer := time.NewTimer(s)
    <-timer.C
    fmt.Println("2-NewTimer", NOW())

    }()
    fmt.Println("leave", NOW())
    return 123
    }
    func main() {
    i := t()
    fmt.Println("i=", i, NOW())
    //for {
    //
    //}
    }

    in- 2021-07-09 16:22:21.4064411 +0800 CST m=+0.003581001
    leave 2021-07-09 16:22:21.4209835 +0800 CST m=+0.018123401
    i= 123 2021-07-09 16:22:21.4209835 +0800 CST m=+0.018123401

    import (
    "fmt"
    "time"
    )

    func NOW() time.Time {
    return time.Now()
    }
    func t() int {
    i := 123
    fmt.Println("in-", NOW())
    go func() {
    fmt.Println("1-NewTimer", NOW())
    s := time.Duration(60) * time.Second
    timer := time.NewTimer(s)
    <-timer.C
    fmt.Println("2-NewTimer", NOW())
    }()
    fmt.Println("leave", NOW())
    defer func() {
    fmt.Println("defer", NOW())
    i = 456
    }()
    return i
    }
    func t1() (i int) {
    i = 123
    fmt.Println("in-", NOW())
    go func() {
    fmt.Println("1-NewTimer", NOW())
    s := time.Duration(60) * time.Second
    timer := time.NewTimer(s)
    <-timer.C
    fmt.Println("2-NewTimer", NOW())
    i = 789
    }()
    defer func() {
    fmt.Println("defer", NOW())
    i = 456
    }()
    fmt.Println("leave", NOW())
    return
    }
    func main() {
    i := t1()
    fmt.Println("i=", i, NOW())
    for {

    }
    }
  • 相关阅读:
    Conv2 GPU加速(有代码有图有真相)
    OpenACC指令适不适合我的程序吗?
    MongoDBHelper
    Js事件 事件绑定
    xslt元素 applyimports
    博客成立,开启一段追逐之旅,留个小小的纪念 ^^
    函数
    C语言基本特性
    预处理
    数组
  • 原文地址:https://www.cnblogs.com/rsapaper/p/14884634.html
Copyright © 2011-2022 走看看