On Wed, Apr 30, 2008 at 11:51:40PM -0300, Juan Alejandro Knight wrote:
> hice una clase para encapsular las funciones POSIX provistas para
> tratar con el bloqueo por lectura/escritura (prefijo pthread_rwlock)
> estaba probando como funciona y note algo interesante: cuando se hacen
> dos lock para escritura, el segundo lockeo no se bloquea, sino que
> sigue como si nada
>
> codigo ejemplo:
> cout << "primer lock de escritura:";
> rwLock.wrlock();
> cout << "OK"<< endl;
> cout << "segundo lock de escritura:";
> rwLock.wrlock();
> cout << "OK"<< endl;
>
> la salida es:
> primer lock de escritura:OK
> segundo lock de escritura:OK
>
> lo comento porque pense que solo se podria escribir de a uno a la vez...
Eso es cierto, pero fijate el manpage: "The calling thread *may*
deadlock if at the time the call is made it holds the read-write lock
(whether a read or write lock).".
O sea, que el comportamiento si un thread tiene el lock y ese mismo
thread trata de adquirirlo es indefinido. Puede deadlockearse, como
puede no hacer nada.
En el caso de la implementacion que vos estas usando, hace esto ultimo.
> si dos hilos hacen un wrlock... quien sabe como va a terminar los
> datos que se quieren proteger
Seguro que anda bien con dos hilos distintos; el caso de un mismo hilo
re-lockeando algo que ya lockeo suele ser especial.
O sea, para implementar eso no vas a tener problemas, el tema esta en
que tu testcase es un caso muy especial y tiene un comportamiento
distinto, por ser un unico hilo.
> por lo visto tendre que utilizar los mutex comunes y silvestres
Los mutex comunes y silvestres tienen este mismo comportamiento: a menos
que vos explicites el tipo de mutex (y tu plataforma soporte un mutex de
tipo no reentrante, cosa que deberia hacer si es compliant con el
estandar), el comportamiento esta indefinido.
Mira el manpage de pthread_mutex_lock lo que te dice: "If the mutex type
is PTHREAD_MUTEX_DEFAULT, attempting to recursively lock the mutex
results in undefined behavior.".
En Linux, el default es no deadlockear, y podes usar
PTHREAD_MUTEX_NORMAL para obtener ese comportamiento. Esto es estandar,
y si queres asegurarte de el mutex actue de esa forma tenes que usar
PTHREAD_MUTEX_NORMAL.
Al igual que el caso anterior, esto es _solo_ para el caso del mismo
thread lockeando dos veces su propio mutex. El uso "normal" entre
threads va a funcionar como uno espera.
> otro tema que me parecio interesante es que hay un solo tipo de
> unlock... como sabe si el unlock es de tipo lectura/escritura?
Primero, se asume que estas unlockeando algo que vos lockeaste
previamente, de lo contrario el comportamiento esta indefinido.
Basandose en esto, cada thread puede saber de que forma lo lockeo (por
ejemplo metiendolo dentro de la estructura misma que representa al
lock), y por lo tanto no le hace falta especificarlo en el unlock. Me
explico?
Muchas gracias,
Alberto
_______________________________________________
Lista de correo Programacion.
[email protected]
http://listas.fi.uba.ar/mailman/listinfo/programacion