【问题标题】:golang sync/atomic package?golang 同步/原子包?
【发布时间】:2017-10-11 21:42:37
【问题描述】:

我写了一段代码来记录请求的数量。

package main

import (
    "log"
    "net/http"
    "runtime"
    "sync/atomic"
)

var count int32 = 0

func test(w http.ResponseWriter, r *http.Request) {
    count = atomic.LoadInt32(&count)
    atomic.AddInt32(&count, 1)
    log.Println("count:", count)
}
func main() {
    runtime.GOMAXPROCS(runtime.NumCPU() - 1)
    http.HandleFunc("/", test)
    http.ListenAndServe(":8080", nil)
}

我已经考虑了并发的条件,所以我使用了原子包。 我通过 apache ab 工具测试代码

ab -c 400 -n 1000 http://localhost:8080/

结果正确: result 但是,有人说他的电脑上得到了1004或其他号码,我测试了很多次代码,但在我的电脑上结果是正确的,是我的方法有问题吗? 我是新来的,提前谢谢。

【问题讨论】:

  • 您使用的包不正确;您不应该直接分配/访问 count 变量,就像您使用 count = ... 一样。
  • 请显示您正在使用的实际代码。此示例不是对 atomic 的有效使用,因为日志行直接访问 count 值,并且您将结果分配回 count
  • 始终使用比赛检测器和vet。 (另外,ab 是一个很差的工具来测试你的服务器,它只是 http/1.0 并且在这里甚至没有使用 keepalive。)
  • 尝试使用像go build -race 这样的-race 标志或使用go run -race main.go 运行来构建您的服务器

标签: go atomic


【解决方案1】:

您错误地使用了sync/atomic 包。如果你有一个原子变量,ALL必须使用原子函数来完成读取和写入。

您的代码已修复,因此count 变量不会以非原子方式写入或读取:

package main

import (
    "log"
    "net/http"
    "runtime"
    "sync/atomic"
)

var count int32

func test(w http.ResponseWriter, r *http.Request) {
    currentCount := atomic.LoadInt32(&count)
    atomic.AddInt32(&count, 1)
    log.Println("count:", currentCount)
}
func main() {
    runtime.GOMAXPROCS(runtime.NumCPU() - 1)
    http.HandleFunc("/", test)
    http.ListenAndServe(":8080", nil)
}

【讨论】:

    猜你喜欢
    • 2018-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    相关资源
    最近更新 更多