英文:
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 <- 1
}
func counter(c <- chan int) {
cur := 0
for v := range c {
cur += v
}
}
func main() {
go counter(counterInput)
// setup http
}
答案2
得分: 1
除非我忽略了什么,在这种情况下,你可以使用sync/atomic
包中的工具(需要将你的类型设置为int32
或int64
),而不是使用锁(或通道)。
不过,文档本身建议你使用其他方式。
这些函数需要非常小心地使用。除了特殊的低级应用程序外,最好使用通道或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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论