Saltar a contenido

Última actualización:2026-10-12

Detección de errores de concurrencia con Helgrind

C++那些事: detección de programación concurrente con helgrind

Normalmente, al escribir programas multihilo, solemos toparnos fácilmente con dos problemas:

  • Un interbloqueo del que no sabemos la causa
  • Datos inconsistentes por un uso incorrecto de los bloqueos entre varios hilos

¿Existe alguna herramienta para detectar estos dos escenarios?

La respuesta es sí: podemos usar helgrind, de valgrind, para detectar ambos problemas. Para que la explicación de este artículo fluya mejor, se introducen varios ejemplos.

Nota: los ejemplos completos y sus versiones corregidas ya están publicados en la comunidad 星球.

Interbloqueo

Supongamos que dos hilos retienen cada uno el bloqueo del otro; con esto podemos simular un interbloqueo, por ejemplo:

void thread_func1() {
    std::lock_guard<std::mutex> lock1(mutex1);
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::lock_guard<std::mutex> lock2(mutex2);
}

void thread_func2() {
    std::lock_guard<std::mutex> lock2(mutex2);
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
    std::lock_guard<std::mutex> lock1(mutex1);
}

El uso de helgrind es el siguiente:

valgrind --tool=helgrind ./a.out 

Así podemos ver el lugar del interbloqueo; en este ejemplo se señala la posición donde los dos hilos se bloquearon mutuamente

thread_func2() (deadlock.cc:18)
thread_func1() (deadlock.cc:12)

deadlock

Carrera de datos

Supongamos que hay una variable compartida que incrementamos 100 000 veces desde varios hilos: ¿cuál será el resultado?

Está claro que aquí se produce el problema de varios hilos compitiendo por una variable global y de que el resultado final es inconsistente; el método de detección con helgrind es el mismo que antes.

int shared_var = 0; 

void increment() {
    for (int i = 0; i < 100000; ++i) {
        ++shared_var; 
    }
}

Con esto podemos ver en qué línea se produce la carrera de datos (data race) y así ir a resolver el problema.

datarace

Para terminar, dejo un par de preguntas:

1.¿Cómo reparar estos dos fragmentos de código defectuosos?

2.Aparte de las herramientas anteriores, ¿hay alguna otra forma?

Fin de esta sección

Temas relacionados

Comentarios