Go http server и глобальные переменные

У меня есть HTTP-сервер. Это написано с ходу. У меня есть такой код:

package main
import (
    "net/http"
    "runtime"
)
var cur = 0
func handler(w http.ResponseWriter, r *http.Request) {
    cur = cur + 1;
}
func main() {
    runtime.GOMAXPROCS(runtime.NumCPU())
    http.HandleFunc("/", handler)
    http.ListenAndServe(":9010", nil)
}

это безопасно? Может быть, мне нужно использовать мьютекс?

2 ответов


нет это не безопасно, да вам понадобится блокировка какой-либо формы. Каждое соединение обрабатывается в своем собственном goroutine. См.реализация Serve () для сведения.

общий шаблон должен использовать goroutine, который проверяет наличие канала и принимает изменения по каналу:

var counterInput = make(chan int)

func handler(w http.ResponseWriter, r *http.Request) {
    counterInput <- 1
}

func counter(c <- chan int) {
    cur := 0
    for v := range c {
        cur += v
    }
}

func main() {
    go counter(counterInput)
    // setup http
}

по теме: считается ли использование глобальных переменных"net/http" хорошей практикой в golang?.


Если я ничего не упускаю, в этом случае вместо использования блокировки (или канала) вы можете использовать инструменты в папке sync/atomic пакет (хотя вам нужно будет сделать свой тип либо int32 или int64)

сама документация рекомендует вам иное.

эти функции требуют большой осторожности, чтобы использоваться правильно. За исключением специальных, низкоуровневых применений, синхронизация более лучшая сделана с каналами или возможности пакета синхронизации. Делитесь памятью, общаясь; не общайтесь, делясь памятью.