19 votos

Es posible determinar el hilo de la celebración de un mutex?

En primer lugar, yo uso la biblioteca pthread escribir multithreading c programa. Hilos siempre colgado de su esperado mutexs. Cuando yo uso el strace de utilidad para encontrar un hilo está en FUTEX_WAIT de estado, quiero saber que hilo sostienen que la exclusión mutua en el tiempo. Pero no sé cómo podría yo hacer. Hay utilidades podría hacer eso? Alguien me dijo que la máquina virtual de java apoyo de esto, Así que quiero saber si el soporte de linux esta característica.

34voto

caf Puntos 114951

Usted puede usar el conocimiento de la exclusión mutua interna para ello. Normalmente esto no sería una idea muy buena, pero está bien para la depuración.

Bajo Linux con NPTL implementación de pthreads (que es moderno glibc), puede examinar el __data.__owner miembro de la pthread_mutex_t estructura para encontrar el hilo que actualmente tiene bloqueado. Esto es cómo hacerlo después de adjuntar al proceso de 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)

(Me cambie a el colgado el hilo, hacer una traza a encontrar el pthread_mutex_lock() que se ha atascado en; cambiar los marcos de pila para averiguar el nombre de la exclusión mutua que se está tratando de bloqueo; a continuación, imprimir el propietario del mutex). Esto me dice que el hilo con el identificador de subproceso 22025 es el culpable.

3voto

Duck Puntos 17054

No sé de ninguna instalación de este tipo así que no creo que usted tendrá que fácilmente - y probablemente no ser tan informativo como usted piensa en ayudar a depurar el programa. Como de baja tecnología, como podría parecer, el registro es tu amigo en la depuración de estas cosas. Inicio de la recogida de su propio pequeño funciones de registro. Ellos no tienen que ser de lujo, sólo tienen que conseguir el trabajo hecho durante 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 no hay nada. Normalmente consigue lo que usted necesita saber.

1voto

Yusuf Khan Puntos 229

Normalmente libc/plataformas llamadas son abstractas OS capa de abstracción. La exclusión mutua de las cerraduras pueden ser rastreados utilizando un propietario variable y pthread_mutex_timedlock. Cuando el hilo se bloquea se debe actualizar la variable con la propia tid(gettid() y también puede tener otra variable para pthread id de almacenamiento) . Así que cuando los otros hilos bloques y agotado en pthread_mutex_timedlock puede imprimir el valor de propietario tid y pthread_id. de esta manera usted puede encontrar fácilmente el subproceso propietario. por favor, encontrar el siguiente fragmento de código, tenga en cuenta que todas las condiciones de error no son manejados

pid_t ownerTid;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

class TimedMutex {
    public:
        TimedMutex()
        {
           struct timespec abs_time;

           while(1)
           {
               clock_gettime(CLOCK_MONOTONIC, &abs_time);
               abs_time.tv_sec += 10;
               if(pthread_mutex_timedlock(&mutex,&abs_time) == ETIMEDOUT)
               {
                   log("Lock held by thread=%d for more than 10 secs",ownerTid);
                   continue;
               }
               ownerTid = gettid();
           }
        }

        ~TimedMutex()
        {

             pthread_mutex_unlock(&mutex);  
        }
};

Hay otras maneras de averiguar las cerraduras, tal vez este enlace puede ayudar http://yusufonlinux.blogspot.in/2010/11/debugging-core-using-gdb.html.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X