Semáforos o Bloqueos en Solaris

Page last edited hace 2059 días 13 horas
De Solaris-ES
Saltar a: navegación, buscar

Sincronización entre Threads los Mutex[editar]

Antes de continuar debemos hacer una aclaración sobre uno de los tipos de bloqueos que se utilizan para la sincronización entre
threads en Solaris, los mutex. 

Mutex o Semáforos[editar]

Es un "bloqueo de exclusión mutua", es creado por la instrucción LDSTUB (load-store-sin firmar-byte), que es
una operación atómica (indivisible) que lee un byte de la memoria y escribe 0xFF en ese lugar. Cuando el bloqueo está
desactivado, se vuelve a escribir 0x00 en la ubicación de memoria.
Si el valor que se lee de la memoria es 0xFF, quiere decir que otro procesador ya ha establecido el bloqueo. En ese momento,
el procesador realiza un "spin locks" es decir entra en un bucle para comprobar si el bloqueo se ha despejado (es decir, si se
ha escrito de nuevo un 0x00). Este tipo de "bloqueo de spin o bucle" se utiliza generalmente cuando se cree que el tiempo de
espera para el bloqueo sera corto. Si la espera es larga, el proceso debe dormir (sleep) para que la CPU pueda ser utilizada
por otro proceso. Esto se conoce como un "block locks").
En resumen, este bloqueo solo permite que un thread acceda al recurso controlado por dicho mutex, por lo tanto una de las causas
que pueden producir una reducción en el rendimiento de nuestro sistema, es que varios threads intenten hacerse a un mismo mutex.
Con lockstat podemos identificar qué está intentando bloquear un mutex.
smtx: es un spin sobre un bloqueo de exclusión mutua, esto lo informa el comando mpstat
En Solaris encontramos dos tipos de bloqueos, los spin locks y los block locks. 

Spin Locks[editar]

Son aquellos en los que los threads no dejan de intentar acceder a él, independientemente de que el bloqueo esté
bloqueado o no, este tipo de bloqueo se implementa cuando queremos que los threads estén continuamente ejecutándose intentando
acceder al bloqueo y sin perder tiempo en esperar algún timeout. 

Sencillamente el thread más rápido en solicitar el bloqueo, justo después de que el bloqueo se ha liberado, será el afortunado.

Block Locks[editar]

Los bloqueos de tipo block no utilizan un método tan agresivo como los spin, sino que los threads que intentan acceder a un
bloqueo de tipo block que esté bloqueado, sencillamente se bloquean a la espera de que el bloqueo vuelva a ser liberado, estos
bloqueo son más lentos con respecto a los anteriores, ya que los procesos deben ser avisados de que el bloqueo se ha liberado.

Los bloqueos de tipo block se suelen utilizar para acceder a recursos de E/S.

Por lo tanto en Solaris podemos encontrar bloqueos de tipo spin o mutex spin y bloqueos de tipo block o mutex block, además de
estos dos tipos existe un tercer tipo de bloqueo, el cual será de tipo spin o de tipo block, dependiendo del estado en el que
esté el thread que lo tiene bloqueado, este tipo de bloqueo se conoce con el nombre de adaptative lock. 

Si el thread que tiene bloqueado el bloqueo al que queremos acceder está corriendo/activo, todos los threads que están
intentando acceder a dicho bloqueo se comportarán como si fuese un spin locks, si por el contrario, el thread que está
utilizando el bloqueo, está en un estado bloqueado, por ejemplo porque esté esperado datos de E/S, todos los threads que
estén intentando acceder al cando, se comportarán como si el bloqueo fuese de tipo block locks.

Adaptative Locks[editar]

El spin mutex hace una llamada al mutex_enter spin si este esta bloqueado utiliza el método de Adaptative Mutex o Semáforos
Adaptativos. Si el bloqueo esta todavia en uso y el dueño del bloqueo esta actualmente activo en un procesador, el thread
intenta adquirir el spin locks, pero si el dueño no esta actualmente activo, el thread intenta adquirir el
block locks (Ej.: interrupción de entrada salida). 

Adaptive mutex spin[editar]

Tener un número alto de intentos sobre bloqueos de estos dos tipos, puede provocar que la cantidad de tiempo asignada al sistema
SYS aumente, obligando al sistema a reducir la cantidad de tiempo que se asigna al usuario y por lo tanto, se producirá una
pérdida de rendimiento es todos los procesos de usuario, al recibir menos tiempo de CPU por parte del Kernel.

Adaptive mutex block[editar]

Si en la salida del comando lockstat vemos que el número de este tipo de bloqueos es considerablemente mayor que cualquiera de
los otros tipos, quizás tengamos un problema con el acceso a un recurso, el cual está bloqueando, tanto al thread que lo está
utilizando como a todos aquellos que están intentando acceder a él. 

Como este tipo de bloqueos no produce un aumento del uso de CPU, el problema de rendimiento no se detectará a simple vista
mediante el valor de uso de CPU, por lo que es aconsejable, siempre que tengamos dudas del rendimiento de nuestro sistema,
aunque el uso de CPU no sea alto, que realicemos un pequeño análisis de los bloqueos mediante el comando lockstat.

Fuentes utilizadas[editar]

http://jjmora.es/rendimiento_tuning_solaris_introduccion
https://forums.oracle.com/forums/thread.jspa?threadID=1950909
http://blogs.oracle.com/clive/entry/smtx_how_many
http://oracle-dba-quickanswers.blogspot.com/2011/10/how-to-analyze-high-cpu-utilization-in.html
http://en.wikipedia.org/wiki/Spinlock