GIL e hyperthreading
Hernan Foffani
hernan en orgmf.com.ar
Jue Mar 25 15:48:48 CET 2004
[Chema Cortes]
> De los comentarios sobre el multihilo de java, recuerdo ahora algo que
> leí sobre metaclases que en su momento no entendí bien, pero que creo
> que está relacionado con este tema del multihilo. Álguien comentaba
> que había conseguido emular el "syncronized" de java con metaclases
> python. No soy nada experto en java, pero entiendo que el
> "syncronized" implementa una especie de bloqueo de acceso a datos
> para ejecución multihilo. ¿No podría ser verse como una solución para
> no tener que usar el GIL en python?
No se exactamente qué es lo que se ha emulado con metaclases.
Conociendo java me imagino que lo que hizo es una forma de evitar que
el programador de python llame .acquire() y .release() a mano.
La instruccion synchronized de java es el equivalente a nuestro
.acquire() y .release(). Internamente hará uso de los mecanismos de
contención propios del JVM. Estos ultimos son los equivalentes a
nuestro GIL.
Mas detalles sobre synchronized.
Lo que hace es declarar una sección critica. Se puede usar de
dos formas:
- como atributo de metodo (todo el metodo es seccion critica)
class Cuenta {
...
public synchronized Deposito(float cantidad) {
this.saldo += cantidad;
if (this.saldo > muchoDinero)
this.saldo += intereses;
}
public synchronized Retiro(float cantidad) {
if (this.saldo > cantidad)
this.saldo -= cantidad;
}
}
- como declaracion de bloque de codigo anonimo (la seccion
critica es el bloque que abarca)
synchronized (objeto) {
// hago cosas peligrosas con objeto.
}
Solo un thread
Java crea el "lock" automaticamente. En el primer caso cualquier
clase que tenga metodos "synchronized", java se encarga de agregar
el lock correspondiente. Lo mismo para el segundo caso.
Python no crea objetos lock automaticamente, eso debe estar
implementado en cada clase.
El equivalente en python del codigo anterior sería, para el
primer caso, algo así:
class Cuenta:
def __init__(self):
self._Cuenta_lock = new Lock()
self.saldo = 0
def deposito(self, cantidad):
self._Cuenta_lock.acquire()
self.saldo += cantidad
if (self.saldo > mucho_dinero):
self.saldo += intereses
self._Cuenta_lock.release()
def retiro(self, cantidad):
self._Cuenta_lock.acquire()
if (self.saldo > cantidad):
self.saldo -= cantidad
self._Cuenta_lock.release()
y para el segundo:
objeto._lock_de_objeto.acquire()
... # seccion critica
objeto._lock_de_objeto.release()
Por eso creo que lo que hizo el autor es una metaclase que
cree el objeto lock al inicializarse y que llame a
.acquire() y .release() antes y despues de la llamada a
cada metodo. Quizas tambien implemento algun mecanismo
para que la sincronizacion se haga sobre los metodos que
el programador decida y no en todos. (No me imagino como
se podría hacer para bloques de codigo anonimos)
El caso de uso de esa metaclase podría ser algo así:
class Cuenta(object):
__metaclass__ = autolock
def retiro(self, cantidad):
if (self.saldo > cantidad):
self.saldo -= cantidad
retiro.synchronized = True
No está mal, no?
Paso de implementar autolock. Se lo dejo a alguno que le
apasionen las metaclases y que le interese el desafío...;-)
Saludos,
-H.
------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es
Más información sobre la lista de distribución Python-es