]> git.llucax.com Git - z.facultad/75.59/filosofos.git/commitdiff
los subo para que no se borren, pero todavia no andan para nada bien..
authortailor <sagardua@uolsinectis.com.ar>
Wed, 23 Nov 2005 13:59:03 +0000 (13:59 +0000)
committertailor <sagardua@uolsinectis.com.ar>
Wed, 23 Nov 2005 13:59:03 +0000 (13:59 +0000)
si me dan algo de tiempo los arreglo..

iniciales, no andan.

src/filosofos.py [new file with mode: 0644]
src/filosofos2.py [new file with mode: 0644]
src/sync.py [new file with mode: 0644]

diff --git a/src/filosofos.py b/src/filosofos.py
new file mode 100644 (file)
index 0000000..27c9690
--- /dev/null
@@ -0,0 +1,80 @@
+#! /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])))
+
diff --git a/src/filosofos2.py b/src/filosofos2.py
new file mode 100644 (file)
index 0000000..5a41148
--- /dev/null
@@ -0,0 +1,85 @@
+#! /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])))
+
diff --git a/src/sync.py b/src/sync.py
new file mode 100644 (file)
index 0000000..cc441c4
--- /dev/null
@@ -0,0 +1,163 @@
+# -*- 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
+