Ir al contenido
learn

10. Estado compartido y thread pool

Un bug concurrente no requiere hardware desafortunado. Dos workers pueden leer el mismo valor, calcular el mismo sucesor y escribirlo. El ejemplo fuerza ese scheduling con una barrera: dos incrementos dejan 1.

System.Threading.Lock es el primitivo moderno de .NET cuando varias lecturas y escrituras forman un invariante. Interlocked sirve para un contador atómico o una operación compare-and-swap. Una colección concurrente protege su propia operación, no una secuencia de negocio completa.

two increments without synchronization: 1
Lock count: 10000
Interlocked count: 10000
AddOrUpdate count: 1000

ConcurrentDictionary.AddOrUpdate puede invocar una factory varias veces bajo contención. Mantén las factories puras y separa los efectos en una operación idempotente.

Parallel.ForEachAsync limita cuerpos activos con MaxDegreeOfParallelism. El programa observa dos cuerpos para un límite de dos. Es un presupuesto local, no backpressure end-to-end.

La starvation aparece cuando hilos bloqueados esperan trabajo que necesita esos mismos workers. Prefiere esperas asíncronas para I/O, limita el CPU y mide con dotnet-counters antes de aumentar mínimos.

Ventana de terminal
dotnet run --project code/csharp-advanced/Advanced -c Release -- l10

La salida portable está en expected/l10.txt.

  1. Sustituye el contador por total y checksum. Explica por qué dos llamadas Interlocked no hacen atómico el par.
  2. Pon una llamada HTTP en GetOrAdd, cuenta las llamadas bajo contención y elimina el efecto.
  3. Compara grados 2, 8 y 64 ante una dependencia limitada a cuatro llamadas.
Soluciones
  1. Protege ambos campos con un solo Lock o sustituye atómicamente un valor inmutable. Dos escrituras atómicas independientes exponen un estado intermedio.
  2. La factory puede ejecutarse varias veces aunque gane un solo valor. El efecto debe ser idempotente y externo al primitivo de colección.
  3. El grado correcto viene del throughput y la latencia medidos; el número de CPU no define la capacidad de la dependencia.