2011-09-14 10 views
8

Suponiendo que un hilo llama con éxito a pthread_mutex_lock, ¿todavía es posible que falle una llamada a pthread_mutex_unlock en ese mismo hilo? Si es así, ¿puedes hacer algo al respecto además de abortar el hilo?¿Cómo manejas los fallos pthread_mutex_unlock?

if(pthread_mutex_lock(&m) == 0) 
{ 
    // got the lock, let's do some work 

    if(pthread_mutex_unlock(&m) != 0) // can this really fail? 
    { 
     // ok, we have a lock but can't unlock it? 
    } 
} 

De this page, posibles errores para pthread_mutex_unlock() son:

[EINVAL] El valor especificado por mutex no se refiere a un objeto mutex inicializado.

Si el bloqueo tuvo éxito, es poco probable que esto falle.

[EAGAIN] El mutex no podía ser adquirido porque se ha excedido el número máximo de cerraduras recursivo para mutex.

¿Realmente? Para desbloquear?

La función pthread_mutex_unlock() puede fallar si:

[EPERM] El hilo actual no posee el mutex.

Nuevamente, si el bloqueo se realizó correctamente, esto tampoco debería ocurrir.

Por lo tanto, mi opinión es si hay un bloqueo exitoso, entonces en esta situación, el desbloqueo nunca debe fallar, haciendo que la comprobación de errores y el código de manejo posterior no tengan sentido.

Respuesta

2

Desde la página del manual de pthread_mutex_unlock:

The pthread_mutex_unlock() function may fail if: 

EPERM 
The current thread does not own the mutex. 

These functions shall not return an error code of [EINTR]. 

Si usted cree que la página del manual, parecería que su caso de error no puede ocurrir.

+0

Gracias, eso es más o menos mi pensamiento también. Actualicé la pregunta para poder aclarar por qué estoy preguntando. Quiero esperar para ver si puedo obtener cualquier otra entrada antes de aceptar una respuesta. –

2

Mucho antes de gritar "victoria". Terminé en esta página buscando una razón por la cual uno de mis programas falló en pthread_mutex_unlock (en HP-UX, no en Linux).

if (pthread_mutex_unlock(&mutex) != 0) 
    throw YpException("unlock %s failed: %s", what.c_str(), strerror(errno)); 

Esto falló en mí, después de muchos millones de ejecuciones felices. errno era EINTR, aunque ahora descubrí que no debería estar revisando el error, sino el valor de retorno. Sin embargo, el valor de retorno NO fue 0. Y puedo demostrar matemáticamente que en ese lugar tengo un candado válido.

Así que vamos a decir que su teoría está bajo tensión, aunque se requiere más investigación ;-)

+0

¡Impresionante! o tal vez no increíble. :-) Este es exactamente el tipo de comentarios que estoy buscando. ¿Eres capaz de reproducir este error o fue una cosa de una sola vez? Sería interesante saber cuál era el valor de retorno real ya que 'pthread_mutex_unlock()' no debe devolver 'EINTR', en' errno' o de lo contrario. –

+0

no he podido reproducirlo.Arreglé mi registro para mostrar el valor de retorno real, en lugar de errno. La próxima vez que suceda (espero que no) te dejaré saber qué fue exactamente ;-) – geert3

+2

Pequeña actualización: he tenido apariciones espurias de desbloqueos fallidos, valor de retorno == 1, que significa "No propietario". Esto resultó ser un error muy sutil. Envuelvo todos mis bloqueos en objetos (el destructor se desbloquea). Esto es útil ya que el bloqueo termina automáticamente junto con el alcance del objeto. En esta función estaba llamando a thread_exit(). La página Man dice que no puede usar variables automáticas después de thread_exit(). Que es exactamente lo que estaba haciendo el destructor de mi objeto de envoltura de cerrojo (implícitamente llamado AFTER thread_exit). – geert3

Cuestiones relacionadas