Go基础 专题
专题目录
您的位置:go > Go基础 专题 > Go原子计数器实例
Go原子计数器实例
作者:--    发布时间:2019-11-20

go语言中管理状态的主要机制是通过通道进行通信。在过去的文章中我们已经看到了这一点,例如工人池。 还有一些其他选项用于管理状态。 这里我们将使用sync/atomic包来实现由多个goroutine访问的原子计数器。

使用一个无符号整数表示计数器(正数)。

为了模拟并发更新,将启动50goroutine,每个增量计数器大约是1毫秒。

为了原子地递增计数器,这里使用adduint64()函数,在ops计数器的内存地址上使用语法。

在增量之间等待一秒,允许一些操作累积。

为了安全地使用计数器,同时它仍然被其他goroutine更新,通过loaduint64提取一个当前值的副本到opsfinal。 如上所述,需要将获取值的内存地址&ops给这个函数。

运行程序显示执行了大约40,000次操作。

所有的示例代码,都放在 f:\worksp\golang 目录下。安装go编程环境请参考:http://www.h3.com/go/go_environment.html

atomic-counters.go的完整代码如下所示 -

package main

import "fmt"
import "time"
import "sync/atomic"

func main() {

    // we'll use an unsigned integer to represent our
    // (always-positive) counter.
    var ops uint64 = 0

    // to simulate concurrent updates, we'll start 50
    // goroutines that each increment the counter about
    // once a millisecond.
    for i := 0; i < 50; i++ {
        go func() {
            for {
                // to atomically increment the counter we
                // use `adduint64`, giving it the memory
                // address of our `ops` counter with the
                // `&` syntax.
                atomic.adduint64(&ops, 1)

                // wait a bit between increments.
                time.sleep(time.millisecond)
            }
        }()
    }

    // wait a second to allow some ops to accumulate.
    time.sleep(time.second)

    // in order to safely use the counter while it's still
    // being updated by other goroutines, we extract a
    // copy of the current value into `opsfinal` via
    // `loaduint64`. as above we need to give this
    // function the memory address `&ops` from which to
    // fetch the value.
    opsfinal := atomic.loaduint64(&ops)
    fmt.println("ops:", opsfinal)
}

执行上面代码,将得到以下输出结果 -

f:\worksp\golang>go run atomic-counters.go
ops: 41360

网站声明:
本站部分内容来自网络,如您发现本站内容
侵害到您的利益,请联系本站管理员处理。
联系站长
373515719@qq.com
关于本站:
编程参考手册