En su respuesta a esta pregunta: Golang for Windows erratic behavior? user @distributed se recomienda para bloquear/sincronizar el acceso a una variable compartida en goroutines concurrentes.Cómo bloquear/sincronizar el acceso a una variable en Go durante las rutinas concurrentes?
¿Cómo puedo hacer eso?
Más sobre el tema:
puedo obtener el código (la función devuelta con un cierre en views
) que se ejecuta en varios goroutines al mismo tiempo:
func makeHomeHandler() func(c *http.Conn, r *http.Request) {
views := 1
return func(c *http.Conn, r *http.Request) {
fmt.Fprintf(c, "Counting %s, %d so far.", r.URL.Path[1:], views)
views++
}
}
Parece que la función IO toma es el momento, y como resultado me da este tipo de salida:
Counting monkeys, 5 so far.
Counting monkeys, 5 so far.
Counting monkeys, 5 so far.
Counting monkeys, 8 so far.
Counting monkeys, 8 so far.
Counting monkeys, 8 so far.
Counting monkeys, 11 so far.
incrementa bien, pero cuando se imprime puedo ver que la operación de impresión + incr la aplicación no es atómica en absoluto.
Si lo cambio a:
func makeHomeHandler() func(c *http.Conn, r *http.Request) {
views := 0
return func(c *http.Conn, r *http.Request) {
views++
// I can only hope that other goroutine does not increment the counter
// at this point, i.e., right after the previous line and before the
// next one are executed!
views_now := views
fmt.Fprintf(c, "Counting %s, %d so far.", r.URL.Path[1:], views_now)
}
}
Parece que funciona bien, pero no estoy completamente seguro si no va a fallar con el tiempo ...
Además de las respuestas mencionan 'sincronización/atomic', el [' paquete expvar'] (https://golang.org/pkg/expvar/) es otra opción si también quiere/necesita mostrar * públicamente * los valores a través de HTTP (por ejemplo, para consultar los valores en un servidor que se ejecuta de forma remota). –