La carrera que no puedes ver en C
El mismo incremento con y sin lock, corrido suficientes veces para perder conteos.
#include <pthread.h>
#include <stdio.h>
#define ROUNDS 200000
static long unsafe_total = 0;
static long safe_total = 0;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
static void *bump(void *arg) {
(void) arg;
for (int i = 0; i < ROUNDS; i++) {
unsafe_total++;
pthread_mutex_lock(&lock);
safe_total++;
pthread_mutex_unlock(&lock);
}
return NULL;
}
int main(void) {
pthread_t a, b;
pthread_create(&a, NULL, bump, NULL);
pthread_create(&b, NULL, bump, NULL);
pthread_join(a, NULL);
pthread_join(b, NULL);
printf("expected %d\n", 2 * ROUNDS);
printf("unsafe %ld\n", unsafe_total);
printf("safe %ld\n", safe_total);
return 0;
}
Cómo funciona
total++son tres operaciones, no una.- Dos hilos que las intercalan pierden actualizaciones.
- El total sin lock sale más bajo, y distinto en cada corrida.
Palabras clave y builtins usados aquí
NULLforintlongreturnstaticvoid
El intento, en números
- Líneas
- 32
- Caracteres a escribir
- 644
- Tokens
- 167
- Ritmo de tres estrellas
- 105 tpm
Al ritmo de tres estrellas de 105 tokens por minuto, este intento toma unos 95 segundos.
Paso 2 de 4 en Bloqueos; paso 5 de 10 en Hilos y concurrencia.