前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >go: 使用原子变量做一个可自动归零的计数器

go: 使用原子变量做一个可自动归零的计数器

作者头像
超级大猪
发布2021-07-01 10:32:49
8320
发布2021-07-01 10:32:49
举报
文章被收录于专栏:大猪的笔记大猪的笔记

最近在做负载均衡,需要制作一个可以并发递增的计数器,用来选取worker,并且在特定的数值需要归零,用代码就是:

代码语言:javascript
复制
counter.SetMax(len(worker))
.....
// 并发,均衡的选取worker
index := counter.Add()
workers[index].Run(args)

第一版用锁可以做到。但想了一下,其实原子变量也能解决这个问题。

代码语言:javascript
复制
// NewCounterIndex ...
func NewCounterIndex(max int64) *CounterIndex {
    c := new(CounterIndex)
    c.max = max
    return c
}

// CounterIndex ...
type CounterIndex struct {
    current int64
    max     int64
}

// Add ...
func (c *CounterIndex) Add() int64 {
    for {
        ret := atomic.AddInt64(&c.current, 1)
        if ret >= atomic.LoadInt64(&c.max) {
            isChange := atomic.CompareAndSwapInt64(&c.current, ret, 0)
            if isChange {
                return 0
            } else {
                continue
            }
        }
        return ret
    }
}

// SetMax ...
func (c *CounterIndex) SetMax(max int64) {
    atomic.StoreInt64(&c.max, max)
}

// Max ...
func (c *CounterIndex) Max() int64 {
    return atomic.LoadInt64(&c.max)
}

测试用例

代码语言:javascript
复制
func TestCounterIndex_Add(t *testing.T) {
    c := NewCounterIndex(100)
    counts := make([]int, 100)
    ret := make(chan int64, 1000)
    go func() {
        for item := range ret {
            counts[int(item)]++
        }
    }()
    for i := 0; i < 1000; i++ {
        go func() {
            tp := c.Add()
            ret <- tp
        }()
    }
    time.Sleep(time.Millisecond * 10)
    close(ret)
    logrus.Infof("counts:%v", counts)
    for _, c := range counts {
        if c != 10 {
            t.Fail()
        }
    }
}

func BenchmarkCounterIndexAdd(b *testing.B) {
    c := NewCounterIndex(100)
    for i := 0; i < b.N; i++ {
        c.Add()
    }
}

性能每次6ns。感觉应该会比加锁好一点点。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-06-29 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
负载均衡
负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档