Concurrencia
25 pasos en 7 series de Go.
La razón por la que la gente elige Go. Goroutines, canales, select, context para cancelar, después el paquete sync para cuando los canales son la herramienta equivocada, y al final los patrones que los combinan.
Veinticinco pasos, el tour de Go más largo de aquí. En Go la concurrencia es tan barata que la usas sin pensarlo, y eso es a la vez el atractivo y la manera en que la gente se mete en problemas.
Goroutines
- Goroutines y WaitGroupLanzar trabajo concurrente y esperar a que termine.
- WaitGroup.GoGo 1.25 agregó Go, que hace el Add y el Done por ti.
- La carrera, y el arregloUn incremento sin proteger pierde actualizaciones; el detector de carreras lo encuentra.
Canales
- Canales sin búferUn envío sin búfer bloquea hasta que otra goroutine recibe: ese es el apretón de manos.
- Canales con búferUn búfer deja que el emisor se adelante, hasta su capacidad.
- CanalesTuberías tipadas que llevan valores entre goroutines.
- Dirección de canalesEl tipo de un parámetro puede restringir un canal a enviar o a recibir.
select
- selectEsperar al canal que esté listo primero.
- select con defaultUn caso default vuelve el select no bloqueante, que es como se sondea.
- TimeoutsUn select contra time.After acota cuánto esperas.
Context
- Context y cancelaciónPropagar plazos y señales de cancelación.
- Contextos con plazoUn contexto baja la cancelación por el árbol de llamadas, y cada espera la respeta.
- Valores en el contextoUn contexto puede llevar valores de la petición, con claves de un tipo no exportado.
Sincronización
- MutexesProteger estado compartido que varias goroutines tocan.
- RWMutexMuchos lectores o un solo escritor, cuando dominan las lecturas.
- sync.OnceInicialización exactamente una vez, segura desde cualquier número de goroutines.
- Atómicos y sync.OnceContadores sin candados, e inicialización de una sola vez.
- Tipos atómicosLos atómicos tipados llevan su propia memoria, así que el mutex sobra.
Patrones
- Pools de workersUn conjunto fijo de goroutines que drena un canal de trabajos.
- Limitar la concurrenciaUn canal con búfer, usado como bolsa de tokens, acota cuántos corren a la vez.
- Fan-inFusionar varios canales en uno, cerrando el resultado cuando todos terminan.
- PipelinesCada etapa lee un canal y devuelve otro, así que las etapas se componen.
- Apagado ordenadoUn canal done, cerrado una sola vez, le avisa a cada worker que pare.
Bis
- crawler.goDescarga varias URL de forma concurrente y reporta cada resultado.
- pipeline.goUn pipeline cancelable de tres etapas con concurrencia acotada.