高并发下Go`net/http`的一些混淆
高并发下的一些混乱 我曾经试过杜松子酒,有点不确定。杜松子酒似乎不安全高并发下Go`net/http`的一些混淆,go,logging,go-gin,Go,Logging,Go 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.Strin
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")
}
测试外壳代码
wrk -t50 -c50 -d 1s http://localhost:8080/test
Gin输出重复数据
=======更新========
即使打印代码是这样的
countCopy := count
go func() {
fmt.Println(countCopy)
}()
我也用测试它,同样的问题
=======更新========
与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)
}
我尝试使用日志包,它可以避免并发goroutine。同样的
log.Println(countCopy)
您必须使用原子的返回值。AddInt64(&count,1),因为在您有机会打印之前,
count
可能会更改:
func Test(c *gin.Context) {
current := atomic.AddInt64(&count, 1)
fmt.Println(current)
c.String(200, "success")
}
您必须使用从
atomic.AddInt64(&count,1)
返回的值,因为count
可能会在您有机会打印它之前更改:
func Test(c *gin.Context) {
current := atomic.AddInt64(&count, 1)
fmt.Println(current)
c.String(200, "success")
}
重复问题在重复问题在