Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go http server and global variables

Tags:

go

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?

like image 430
drlexa Avatar asked Sep 20 '13 18:09

drlexa


People also ask

Does Go have global variables?

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.

How do you use global variables in go?

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.

What does HTTP ListenAndServe do?

ListenAndServe function, which tells the global HTTP server to listen for incoming requests on a specific port with an optional http. Handler .

Can global variables be used anywhere?

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.


2 Answers

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?.

like image 189
nemo Avatar answered Sep 24 '22 21:09

nemo


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.

like image 45
justinas Avatar answered Sep 23 '22 21:09

justinas