高并发下的一些困惑。
我使用 wrk测试 Gin ,有一些不确定性。 Gin 似乎并发不安全。
package main
import (
"fmt"
"sync/atomic"
"github.com/gin-gonic/gin"
)
var count int64 = 0
func Test(c *gin.Context) {
atomic.AddInt64(&count, 1)
fmt.Println(count)
c.String(200, "success")
}
func main() {
gin.SetMode(gin.DebugMode)
router := gin.New()
router.GET("test", Test)
router.Run(":8080")
}
测试shell代码
wrk -t50 -c50 -d 1s http://localhost:8080/test
gin输出重复数据
========更新========
即使打印代码是这样的。
countCopy := count
go func() {
fmt.Println(countCopy)
}()
我也用ab测试一下,同样的问题。
========更新========和net/http一样,还是有重复数据。
package main
import (
"fmt"
"net/http"
"sync/atomic"
)
var count int64 = 0
func Test(w http.ResponseWriter, req *http.Request) {
atomic.AddInt64(&count, 1)
fmt.Println(count)
w.Write([]byte("success"))
}
func main() {
http.HandleFunc("/test", Test)
http.ListenAndServe(":8080", nil)
}
我尝试使用日志包,它对并发 goroutines 是安全的。一样。
log.Println(countCopy)
最佳答案
您必须使用 atomic.AddInt64(&count, 1)
的返回值,因为 count
可以在您有机会打印之前更改:
func Test(c *gin.Context) {
current := atomic.AddInt64(&count, 1)
fmt.Println(current)
c.String(200, "success")
}
关于go - 高并发下Go `net/http`的一些困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50267112/