6

我有一个 http 服务器。它是用 Go 编写的。我有这个代码:

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)
}

安全吗?可能我需要使用互斥锁吗?

4

2 回答 2

5

不,这不安全,是的,您将需要某种形式的锁定。每个连接都在自己的 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 中使用全局变量是否被认为是一种好习惯?.

于 2013-09-20T18:15:49.243 回答
1

除非我忽略了某些东西,在这种情况下,您可以使用包中的工具sync/atomic,而不是使用锁(或通道) (尽管您需要使用int32int64

但是,文档本身会建议您。

这些功能需要非常小心才能正确使用。除了特殊的低级应用程序外,最好使用通道或同步包的工具来完成同步。通过通信共享内存;不要通过共享内存进行通信。

于 2013-09-20T18:42:43.340 回答