Go HTTP服务器和全局变量

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

这个操作安全吗?也许我需要使用互斥锁?

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
}

相关: 在golang中,“net/http”使用全局变量是否被认为是一种良好的实践?


1

除非我漏看了什么,否则在这种情况下,您可以使用sync/atomic包中找到的工具(尽管您需要将类型更改为int32int64),而不是使用锁(或通道)。

不过,文档本身建议您不要这样做。

这些函数需要非常小心地使用才能正确地使用。除了特殊的低级应用程序之外,最好使用通道或sync包的设施进行同步。通过通信共享内存;不要通过共享内存进行通信。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接