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
)
сама документация рекомендует вам иное.
эти функции требуют большой осторожности, чтобы использоваться правильно. За исключением специальных, низкоуровневых применений, синхронизация более лучшая сделана с каналами или возможности пакета синхронизации. Делитесь памятью, общаясь; не общайтесь, делясь памятью.