tag - threads en c




¿Es posible determinar el hilo que sostiene un mutex? (3)

En primer lugar, uso la biblioteca pthread para escribir el programa C de multiproceso. Los hilos siempre colgaban de sus mutex esperados. Cuando utilizo la utilidad strace para encontrar que un subproceso está en estado FUTEX_WAIT , quiero saber qué subproceso contiene ese mutex en ese momento. Pero no sé cómo podría hacerlo. ¿Hay alguna utilidad que pueda hacer eso?

Alguien me dijo que la máquina virtual Java es compatible con esto, por lo que quiero saber si Linux es compatible con esta función.



No conozco ninguna instalación de este tipo, por lo que no creo que te salgas tan fácilmente, y probablemente no sea tan informativo como piensas para ayudar a depurar tu programa. Por baja que parezca la tecnología, el registro es tu amigo en la depuración de estas cosas. Comience a recoger sus propias funciones de registro pequeño. No tienen que ser elegantes, solo tienen que hacer el trabajo mientras se hace la depuración.

Lo siento por el C ++ pero algo como:

void logit(const bool aquired, const char* lockname, const int linenum)
{
    pthread_mutex_lock(&log_mutex);

    if (! aquired)
        logfile << pthread_self() << " tries lock " << lockname << " at " << linenum << endl;
    else
        logfile << pthread_self() << " has lock "   << lockname << " at " << linenum << endl;

    pthread_mutex_unlock(&log_mutex);
}


void someTask()
{
    logit(false, "some_mutex", __LINE__);

    pthread_mutex_lock(&some_mutex);

    logit(true, "some_mutex", __LINE__);

    // do stuff ...

    pthread_mutex_unlock(&some_mutex);
}

El registro no es una solución perfecta pero nada lo es. Por lo general, te da lo que necesitas saber.


Puede utilizar el conocimiento de los internos de mutex para hacer esto. Normalmente esto no sería una buena idea, pero está bien para la depuración.

Bajo Linux con la implementación NPTL de pthreads (que es cualquier glibc moderno), puede examinar el miembro __data.__owner de la estructura pthread_mutex_t para averiguar el hilo que actualmente está bloqueado. Esto es cómo hacerlo después de adjuntar al proceso con gdb :

(gdb) thread 2
[Switching to thread 2 (Thread 0xb6d94b90 (LWP 22026))]#0  0xb771f424 in __kernel_vsyscall ()
(gdb) bt
#0  0xb771f424 in __kernel_vsyscall ()
#1  0xb76fec99 in __lll_lock_wait () from /lib/i686/cmov/libpthread.so.0
#2  0xb76fa0c4 in _L_lock_89 () from /lib/i686/cmov/libpthread.so.0
#3  0xb76f99f2 in pthread_mutex_lock () from /lib/i686/cmov/libpthread.so.0
#4  0x080484a6 in thread (x=0x0) at mutex_owner.c:8
#5  0xb76f84c0 in start_thread () from /lib/i686/cmov/libpthread.so.0
#6  0xb767784e in clone () from /lib/i686/cmov/libc.so.6
(gdb) up 4
#4  0x080484a6 in thread (x=0x0) at mutex_owner.c:8
8               pthread_mutex_lock(&mutex);
(gdb) print mutex.__data.__owner
$1 = 22025
(gdb)

(Cambio al hilo colgado; realice un seguimiento para encontrar el pthread_mutex_lock() que está atascado; cambie los cuadros de la pila para averiguar el nombre del mutex que está intentando bloquear; luego, imprima el propietario de ese mutex). Esto me dice que el hilo con ID LWP 22025 es el culpable.

Luego puede usar el thread find 22025 para encontrar el número de hilo gdb para ese hilo y cambiarlo.







mutex