Некоторая путаница с Go `net / http` при высоком параллелизме - PullRequest
0 голосов
/ 10 мая 2018

Некоторая путаница при высоком параллелизме.

Я использую wrk для проверки Джина, есть некоторая неопределенность.Похоже, джин не безопасен для параллелизма.

  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

Вывод повторяющихся данных в джин

duplicate data

======== update ========

, даже если код печати такой.

  countCopy := count
  go func() {
    fmt.Println(countCopy)
  }()

Я также использую ab , проверьте его, та же проблема.

======== update ========

То же самое с 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)

  }

data

Я пытаюсь использовать пакет журнала, который защищен от одновременных загрузок.То же самое.

log.Println(countCopy)

1 Ответ

0 голосов
/ 10 мая 2018

Вы должны использовать возвращаемое значение из atomic.AddInt64(&count, 1), так как count может измениться, прежде чем вы сможете распечатать его:

func Test(c *gin.Context) {
    current := atomic.AddInt64(&count, 1)
    fmt.Println(current)
    c.String(200, "success")
}
...