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?
A global variable refers to a variable that is defined outside a function. Global variables can be accessed throughout the program or within any function in the defined package. Follow us along as we explore the concept of global variables in the go programming language.
Global variables are defined outside of a function, usually on top of the program. Global variables hold their value throughout the lifetime of the program and they can be accessed inside any of the functions defined for the program.
ListenAndServe function, which tells the global HTTP server to listen for incoming requests on a specific port with an optional http. Handler .
Global variables, variables declared outside of setup() and draw(), may be used anywhere within the program. If a local variable is declared with the same name as a global variable, the program will use the local variable to make its calculations within the current scope.
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
}
Related: Is "net/http"'s use of global variables considered a good practice in golang?.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With