Detector de Carreras: Ejecución e Interpretación de Salida
El detector de carreras de Go instrumenta los accesos a memoria en tiempo de compilación para encontrar lecturas y escrituras concurrentes no sincronizadas.
Busca en todas las páginas de la documentación
El detector de carreras de Go instrumenta los accesos a memoria en tiempo de compilación para encontrar lecturas y escrituras concurrentes no sincronizadas.
Ejecútalo en CI en paquetes que usan goroutines; aprende a leer sus informes para corregir errores reales, no para silenciar ruido.
Habilita con -race en go test, go run o go build.
Una carrera de datos ocurre cuando dos goroutines acceden a la misma ubicación de memoria, al menos una es una escritura, y no hay un ordenamiento "happens-before".
Los informes muestran las pilas de goroutines para ambos lados de la carrera.
Corrige con mutexes, canales, atómicos o reestructurando la propiedad; nunca digas "pasó una vez sin -race".
Tarjeta de receta de referencia rápida, lista para copiar y pegar.
go test -race ./...
go run -race .
go build -race -o bin/app .
./bin/app # solo en staging - las compilaciones con -race son más lentas y usan más memoriaCuándo usar esto:
-count=10 paralelo.Código con errores y patrón de salida típico del detector:
package counter
import "sync"
var n int // BUG: no sincronizado
func Inc() { n++ }
func BrokenParallel(wg *sync.WaitGroup) {
for i := 0; i < 100; i++ {
wg.Add(1)
go func() {
defer wg.Done()
Inc()
}()
}
}$ go test -race ./...
==================
WARNING: DATA RACE
Write at 0x... by goroutine 7:
example.com/counter.Inc()
example.com/counter.BrokenParallel.func1()
Previous read at 0x... by goroutine 6:
...
==================Versión corregida:
var (
mu sync.Mutex
n int
)
func Inc() {
mu.Lock()
n++
mu.Unlock()
}Lo que esto demuestra:
Inc y sus llamadores aparecen en las pilas; comienza a leer desde los marcos de tu código.-race hasta que esté limpio.| Sección | Significado |
|---|---|
Write at / Read at | Tipo de acceso y dirección |
by goroutine N | Pila de un participante |
Previous read/write | Pila del otro participante |
Goroutine N created at | Dónde comenzó la goroutine |
| Patrón | Corrección |
|---|---|
| Mapa compartido sin bloqueo | Mutex o pasar la propiedad a través de un canal |
| Comprobar antes de actuar | Bloquear toda la comprobación+acción o usar CAS atómico |
| Carrera de inicialización perezosa | sync.Once |
| Añadir a una slice compartida | Mutex o una goroutine escritora única |
# Búsqueda de carreras intermitentes
go test -race -count=50 ./pkg
# Fragmento de CI
go test -race -short ./...-race en CI - Las carreras llegan a producción. Corrección: trabajo obligatorio de -race en los paquetes principales.-parallel 1 - Oculta las carreras. Corrección: sincronizar el código bajo prueba.sync.-race limpio - Las carreras lógicas permanecen. Corrección: atómicos para contadores simples; mutex para invariantes.go test -timeout, detectores de interbloqueo en staging.| Alternativa | Usar Cuando | No Usar Cuando |
|---|---|---|
Pruebas con -race | Verificación de concurrencia por defecto | Binarios de producción |
Mutex + revisión de código | Prevenir carreras por diseño | Sustituto de ejecutar siempre -race |
go test -fuzz | Errores impulsados por la entrada | Carreras de datos sin concurrencia de fuzzing |
| Sanitizadores de hilos (otros idiomas) | N/A en Go | Código Go - usar el detector de carreras incorporado |
Sí, a menudo varias veces más lento.
Ejecútalo en CI nocturno o por PR para los paquetes afectados si la suite completa es demasiado lenta.
Sí, las carreras dependen del tiempo.
-race fuerza la instrumentación de intercalación para exponerlas.
No para producción sensible a la latencia.
Usa entornos de staging o de prueba dedicados con compilaciones -race.
Los informes aún muestran las pilas.
Serializa init con sync.Once o evita globales mutables.
La transferencia está sincronizada, pero mutar una struct después de enviar un puntero todavía produce una carrera si otras goroutines lo leen sin sincronización.
Las operaciones atómicas correctas no producen carreras en la misma palabra.
Mezclar atómicos y mutex en datos superpuestos sigue siendo propenso a errores.
No hay supresión oficial como en algunas herramientas de C.
Corrige el error o refactoriza el diseño de la prueba.
Soportado en linux/amd64, darwin/amd64, darwin/arm64, windows/amd64, y otros puertos listados.
Consulta la documentación de go.dev para la lista actual de plataformas.
Una carrera necesita dos accesos concurrentes.
Cada pila es la participación de una goroutine.
Los linters detectan algunas APIs propensas a carreras, pero no reemplazan a -race.
Usa ambos en CI.
Versiones de Stack: Esta página fue escrita para Go 1.26.x (predeterminado Green Tea GC, modernizadores go fix - verificar parche en la compilación), chi (última versión - verificar en la compilación), gin (última versión - verificar en la compilación), echo (última versión - verificar en la compilación), google.golang.org/grpc (última versión - verificar en la compilación), sigs.k8s.io/controller-runtime (última versión - verificar en la compilación), kubebuilder (última versión - verificar en la compilación), tinygo (última versión - verificar objetivos de placa en la compilación), wazero (última versión - verificar en la compilación) y golangci-lint (última versión - verificar conjunto de linters en la compilación).
Revisado por Chris St. John·Última actualización: 18 jul 2026