登录
首页 >  Golang >  Go问答

使用计时器自动清除变量

来源:stackoverflow

时间:2024-03-10 21:45:25 271浏览 收藏

小伙伴们有没有觉得学习Golang很有意思?有意思就对了!今天就给大家带来《使用计时器自动清除变量》,以下内容将会涉及到,若是在学习中对其中部分知识点有疑问,或许看了本文就能帮到你!

问题内容

我有一个 golang 脚本,每次通过验证过程时都会将 IP 列入白名单。 我想知道是否有办法添加一个计时器来清除 var 可能每 30 分钟或每小时一次?(golang)

ipwhite = []字符串{}


正确答案


http 处理程序在单独的 goroutine 中并发运行。因此,协调对 ipwhite 的访问以避免竞争条件至关重要。这可以通过sync.Mutex或渠道完成。

处理过期的主要方法有两种:

  1. 启动一个单独的 goroutine 以使旧条目过期。这需要额外的协调来启动/停止 goroutine/计时器等,并且可能会更加复杂。
  2. 在添加/查找过程中检查并处理过期情况。

这是一个使用 (2) 的简单解决方案:

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    ipwhite := newexpiryset(3 * time.second)

    fmt.println(ipwhite.lookup("1.1.1.1"))
    ipwhite.add("1.1.1.1")
    ipwhite.add("1.1.1.1")
    fmt.println(ipwhite.lookup("1.1.1.1"))
    time.sleep(4 * time.second)
    fmt.println(ipwhite.lookup("1.1.1.1"))
}

type expiryset struct {
    timeout time.duration

    mu         sync.mutex
    items      map[string]entry
    nextexpire time.time
}

func newexpiryset(timeout time.duration) *expiryset {
    return &expiryset{
        timeout: timeout,
        items:   make(map[string]entry),
    }
}

type entry struct {
    expiry time.time
    count  int
}

func (s *expiryset) add(v string) {
    s.lookup(v, true)
}

func (s *expiryset) lookup(v string) int {
    return s.lookup(v, false)
}

func (s *expiryset) lookup(v string, update bool) int {
    now := time.now()

    // all lookups/modifications must be done while the mutex is locked.
    s.mu.lock()
    defer s.mu.unlock()

    // periodically check whether any entries need expiry by scanning
    // the entire map.
    if s.nextexpire.before(now) {
        for k, e := range s.items {
            if e.expiry.before(now) {
                delete(s.items, k)
            }
        }
        s.nextexpire = now.add(s.timeout)
    }

    e, ok := s.items[v]
    // always check whether the current entry needs to be expired.
    if ok && e.expiry.before(now) {
        e = entry{}
    }

    if update {
        e.expiry = now.add(s.timeout)
        e.count++
        s.items[v] = e
    }

    return e.count
}

改进的版本可能会使用最小堆来进行过期,并使用单独的 goroutine 来按需过期,并可能为 go1.18+ 键入参数(供读者练习)。

输出:

$ ./ipwhite 
0
2
0

今天关于《使用计时器自动清除变量》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>