--- /dev/null
+#! /usr/bin/env python2.4
+import threading
+import sys
+import random
+import time
+from sync import *
+
+
+palitos = []
+semaforos = []
+
+
+class filosofo(threading.Thread):
+ def __init__(self, numeracion, cant):
+ threading.Thread.__init__(self)
+ self.id = numeracion
+ self.rnd = random.Random()
+ self.cant = cant # cantidad de veces que va a comer
+ self.comi = 0 # cantidad de veces que comio
+ self.derecho = False
+ self.izquierdo = False
+ self.start()
+
+ @synchronized('Lock')
+ def agarrarPalitoDerecho(self):
+ if self.id+1 == len(palitos): ind = 0
+ else: ind = self.id+1
+ self.derecho = palitos[ind]
+ if self.derecho:
+ print 'Soy '+str(self.id)+' y agarre el palito derecho'
+ else: self.derecho = False
+
+ @synchronized('Lock')
+ def agarrarPalitoIzquierdo(self):
+ self.izquierdo = palitos[self.id]
+ if self.izquierdo:
+ print 'Soy '+str(self.id)+' y agarre el palito izquierdo'
+ else: self.izquierdo = False
+
+ def pensar(self):
+ t = self.rnd.randint(0,5)
+ print 'Soy '+str(self.id)+' y voy a pensar durante '+str(t)+' segundos'
+ time.sleep(t)
+
+ def comer(self):
+ if self.derecho and self.izquierdo:
+ print 'Soy '+str(self.id)+' y voy a comer'
+ self.comi = self.comi + 1
+ self.izquierdo = self.derecho = False
+ time.sleep(self.rnd.randint(0,5))
+ if self.id+1 == len(palitos): ind = 0
+ else: ind = self.id+1
+ palitos[self.id] = True
+ palitos[ind] = True
+ 'Soy '+str(self.id)+' y solte los palitos'
+ return True
+ else: return False
+
+ def lleno(self):
+ if self.cant == self.comi: return True
+ else: return False
+
+ def run(self):
+ while not self.lleno():
+ self.agarrarPalitoDerecho()
+ self.agarrarPalitoIzquierdo()
+ if not self.comer():
+ self.pensar()
+ else: time.sleep(5) #comiendo
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print "Modo de uso: "+ str(sys.argv[0]) + "<Cantidad de chinos invitados a la fiesta> <Cantidad de rondas que estara pensando o comiendo cada chino>"
+ exit
+
+ chinos = []
+ for i in range(int(sys.argv[1])):
+ palitos.append(True)
+ chinos.append(filosofo(i,int(sys.argv[2])))
+
--- /dev/null
+#! /usr/bin/env python2.4
+import threading
+import sys
+import random
+import time
+from sync import *
+
+
+palitos = []
+semaforos = []
+
+
+class filosofo(threading.Thread):
+ def __init__(self, numeracion, cant):
+ threading.Thread.__init__(self)
+ self.id = numeracion
+ self.rnd = random.Random()
+ self.cant = cant # cantidad de veces que va a comer
+ self.comi = 0 # cantidad de veces que comio
+ self.derecho = False
+ self.izquierdo = False
+ self.start()
+
+ def agarrarPalitoDerecho(self):
+ if self.id+1 == len(palitos): ind = 0
+ else: ind = self.id+1
+ semaforos[ind].acquire()
+ self.derecho = palitos[ind]
+ if self.derecho:
+ print 'Soy '+str(self.id)+' y agarre el palito derecho'
+ else: self.derecho = False
+ semaforos[ind].release()
+
+ def agarrarPalitoIzquierdo(self):
+ semaforos[self.id].acquire()
+ self.izquierdo = palitos[self.id]
+ if self.izquierdo:
+ print 'Soy '+str(self.id)+' y agarre el palito izquierdo'
+ else: self.izquierdo = False
+ semaforos[self.id].release()
+
+ def pensar(self):
+ t = self.rnd.randint(1,5)
+ print 'Soy '+str(self.id)+' y voy a pensar durante '+str(t)+' segundos'
+ time.sleep(t)
+
+ def comer(self):
+ t = self.rnd.randint(1,5)
+ if self.derecho and self.izquierdo:
+ print 'Soy '+str(self.id)+' y voy a comer '+ str(t) + ' segundos'
+ self.comi = self.comi + 1
+ self.izquierdo = self.derecho = False
+ time.sleep(t)
+ if self.id+1 == len(palitos): ind = 0
+ else: ind = self.id+1
+ palitos[self.id] = True
+ palitos[ind] = True
+ print 'Soy '+str(self.id)+' y solte los palitos'
+ return True
+ else: return False
+
+ def lleno(self):
+ if self.cant == self.comi: return True
+ else: return False
+
+ def run(self):
+ time.sleep(self.rnd.randint(1,5))
+ while not self.lleno():
+ self.agarrarPalitoDerecho()
+ self.agarrarPalitoIzquierdo()
+ if not self.comer():
+ self.pensar()
+ else: time.sleep(5) #comiendo
+
+if __name__ == '__main__':
+ if len(sys.argv) < 3:
+ print "Modo de uso: "+ str(sys.argv[0]) + "<Cantidad de chinos invitados a la fiesta> <Cantidad de rondas que estara pensando o comiendo cada chino>"
+ exit
+
+ chinos = []
+ for i in range(int(sys.argv[1])):
+ palitos.append(True)
+ semaforos.append(threading.Semaphore(1))
+ chinos.append(filosofo(i,int(sys.argv[2])))
+
--- /dev/null
+# -*- coding: iso-8859-1 -*-
+# vim: set expandtab tabstop=4 shiftwidth=4 :
+
+from threading import Lock
+
+_gettersetter_code = """
+def get(self):
+ lock = getattr(self, '__%(attr)sLock')
+ lock.acquire()
+ val = getattr(self, '__%(attr)s')
+ lock.release()
+ return val
+def set(self, val):
+ if not hasattr(self, '__%(attr)sLock'):
+ setattr(self, '__%(attr)sLock', Lock())
+ lock = getattr(self, '__%(attr)sLock')
+ lock.acquire()
+ setattr(self, '__%(attr)s', val)
+ lock.release()
+"""
+
+__all__ = ('SyncProp', 'Synchronizable', 'synchronized')
+
+class SyncProp:
+ """Synchronized property.
+ When using a class attribute as an SyncProp object it protects the property
+ access and modification using a lock (mutex). You should allways inherit
+ from Synchronizable if you are using SyncProp's.
+ Note that SyncProp only works with non-mutable objects, because it will not
+ protect from method calls.
+
+ Example:
+ class MyClass(Synchronizable):
+ prop = SyncProp("My property.")
+
+ c = MyClass()
+ c.prop = 1 # is like:
+ # c.__propLock.acquire()
+ # c.prop = 1
+ # c.__propLock.release()
+ print c.prop # is like:
+ # c.__propLock.acquire()
+ # tmp = c.prop
+ # c.__propLock.release()
+ # print tmp
+ # del tmp
+ """
+ def __init__(self, docstring=''):
+ "Constructor"
+ self.doc = docstring
+
+class SynchronizableMeta(type):
+ """Synchronizable meta class.
+ This is the class that makes all the magic. It translate SyncProp attributes
+ to the synchronized properties.
+ """
+ def __new__(cls, clsname, bases, attrs):
+ "Translates SyncProp attributes to the synchronized properties."
+ cls = type.__new__(cls, clsname, bases, attrs)
+ for (attr, obj) in attrs.iteritems():
+ if isinstance(obj, SyncProp):
+ exec _gettersetter_code % {'attr': attr}
+ setattr(cls, attr, property(get, set, None, obj.doc))
+ return cls
+
+class Synchronizable(object):
+ """Synchronizable classes base.
+ All the classes winth SyncProp attributes should inherit from this class to
+ wrap the SyncProp attributes between locks (mutexes).
+
+ Example:
+ class MyClass(Synchronizable):
+ prop = SyncProp("My property.")
+
+ c = MyClass()
+ c.prop = 1 # is like:
+ # c.__propLock.acquire()
+ # c.prop = 1
+ # c.__propLock.release()
+ print c.prop # is like:
+ # c.__propLock.acquire()
+ # tmp = c.prop
+ # c.__propLock.release()
+ # print tmp
+ # del tmp
+ """
+
+ __metaclass__ = SynchronizableMeta
+
+def synchronized(lockattrname=None):
+ """Synchronized method decorator.
+ This decorator make a method call synchronized. It's not required to
+ inherit classes with synchronized methods from Synchrnonizable. You
+ can optionally pass to the decorator the name of the lock (mutex)
+ attribute to use.
+
+ Example:
+ class MyClass:
+ @synchronized
+ def syncMethod(self, msg):
+ print self.__name__, msg
+
+ c = MyClass()
+ c.syncMethod("hi!") # is like:
+ # c.__syncMethodLock.acquire()
+ # c.synchMethod("hi!")
+ # c.__syncMethodLock.release()
+ """
+
+ def wrapper(method):
+ def syncMethod(self, *args, **kargs):
+ "Wrapper method."
+ name = lockattrname
+ if name is not None:
+ name = '__' + method.__name__ + 'Lock'
+ if not hasattr(self, name):
+ setattr(self, name, Lock())
+ lock = getattr(self, name)
+ lock.acquire()
+ ret = method(self, *args, **kargs)
+ lock.release()
+ return ret
+ return syncMethod
+ return wrapper
+
+# Simple test
+if __name__ == '__main__':
+
+ import time
+ from threading import Thread, enumerate, currentThread, Lock
+
+ class Obj:
+ "Dummy test class"
+
+ class SyncObj(Synchronizable):
+ "Dummy test class"
+ value = SyncProp("Dummy value")
+
+ def sleep(self):
+ name = currentThread().getName()
+ print name, 'durmiendo'
+ time.sleep(float('0.'+name))
+ sleep = synchronized(sleep)
+
+ def incObj():
+ for i in xrange(100):
+ #lock.acquire()
+ obj.value = 0xf0f0f0f0f0f0f0+(i<<20)+(i<<14)+(i<<6)
+ #lock.release()
+ #time.sleep(0.0000014)
+ #obj.sleep()
+
+ lock = Lock()
+ obj = SyncObj()
+ #obj = Obj()
+ obj.value = 100000000000000000000000000000
+ for i in xrange(200):
+ Thread(target=incObj, name=str(i+1)).start()
+ for t in enumerate():
+ if t is not currentThread():
+ t.join()
+ print obj.value
+