Go语言的HTTP服务器和全局变量

huangapple go评论150阅读模式
英文:

Go http server and global variables

问题

我有一个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)
}

这段代码安全吗?
也许我需要使用互斥锁(mutex)吗?

英文:

I have a http server. It is written with Go.
I have this code:

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

Is it safe?
May be I need to use a mutex?

答案1

得分: 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)
    // 设置http
}

相关链接:https://stackoverflow.com/questions/12230643/is-net-https-use-of-global-variables-considered-a-good-practice-in-golang。

英文:

No it is not safe, yes you will need locking of some form.
Each connection is handled in its own goroutine. See the Serve() implementation for details.

A general pattern is to use a goroutine which checks for a channel and accepts changes
via a channel:

var counterInput = make(chan int)

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

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

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

Related: https://stackoverflow.com/questions/12230643/is-net-https-use-of-global-variables-considered-a-good-practice-in-golang.

答案2

得分: 1

除非我忽略了什么,在这种情况下,你可以使用sync/atomic包中的工具(需要将你的类型设置为int32int64),而不是使用锁(或通道)。

不过,文档本身建议你使用其他方式。

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

英文:

Unless I'm overlooking something, in this case, instead of using a lock (or a channel), you could use the tools found in the sync/atomic package (though you'll need to make your type either int32 or int64)

The documentation itself recommends you otherwise, though.

>These functions require great care to be used correctly. Except for special, low-level applications, synchronization is better done with channels or the facilities of the sync package. Share memory by communicating; don't communicate by sharing memory.

huangapple
  • 本文由 发表于 2013年9月21日 02:06:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/18923123.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定