En C, por defecto el programa se ejecuta en un único hilo, así que los núcleos adicionales del procesador quedan sin aprovechar hasta que se crean más hebras con thrd_create y se esperan con thrd_join, disponibles en el encabezado . Esta función es opcional según el estándar C11: si STDC_NO_THREADS está definido, el compilador no la ofrece; la biblioteca de Apple nunca la ha incluido y glibc solo la añadió en la versión 2.28 (2018), por lo que en esos sistemas se recurre a POSIX (pthread_create, pthread_join).
Cuando varias hebras comparten memoria y al menos una escribe, el lenguaje considera que hay una carrera de datos y el comportamiento es indefinido. Para evitarlo se usan variables atómicas declaradas con , que garantizan lecturas siempre válidas. Además, el hardware y el compilador pueden reordenar instrucciones, lo que obliga a fijar un modelo de memoria: secuencialmente consistente por defecto, relajado en el extremo más débil, o release/acquire como punto intermedio. La semántica release impide reordenar operaciones anteriores y acquire garantiza que, tras la carga, se ven todas las escrituras previas.
El artículo lo ilustra con un patrón clásico: un recurso compartido con contador de referencias. El decremento con release evita que se libere el recurso antes de acceder a él, y un acquire en el último dueño asegura que el resto de hebras han terminado. Como ejemplo práctico construye un array compartido con copy-on-write, donde solo el contador de referencias es atómico y el payload permanece inmutable mientras otros lo leen. El autor concluye que la operación clave es atomic_fetch_sub_explicit, que devuelve el valor previo y permite saber de forma fiable quién es el último en liberar.
