Foros del Web » Programando para Internet » Python »

[SOLUCIONADO] Problema con hilos

Estas en el tema de Problema con hilos en el foro de Python en Foros del Web. Hola a todos. Estoy comenzando con Python, haciendo un curso, en el que nos han dado un problema. Mi problema es que no termino de ...
  #1 (permalink)  
Antiguo 15/05/2015, 12:19
 
Fecha de Ingreso: mayo-2015
Mensajes: 15
Antigüedad: 9 años, 6 meses
Puntos: 0
Sonrisa Problema con hilos

Hola a todos. Estoy comenzando con Python, haciendo un curso, en el que nos han dado un problema.
Mi problema es que no termino de entender hilos y lo poco que encuentro dando vueltas está en inglés.
Tengo la idea de como hacer funcionar el programa. mi problema es la implementación de hilos "Threads".
Queria ver si podian darme una mano. Les muestro lo que tengo.
Entre las lineas 57 y 60 estaria mi problema, el buffer.
Y en la consulta de vuelos "lector" tenia pensado hacer 2 listas: Una para reservas, con los 1000 asientos con booleanos y otra solo con los asientos reservados. Que no lo hice todavia, me importa mas el buffer.
Agradecería mucho ayuda

Código Python:
Ver original
  1. # Simular con hilos un sistema de reservación de vuelos. Las personas pueden consultar y reservar vuelos.
  2. # Hacer la sincronización con múltiples personas accediendo al registro de vuelos.
  3. # Cuando se reserva no se puede consultar y viceversa. Lanzar 20 hilos
  4. # 1000 lugares en el avion.
  5.  
  6. import threading
  7. import random
  8. import time
  9.  
  10. class Reserva(threading.Thread):
  11.    
  12.     def __init__(self, nombreHilo, asientos, condicion, cant):
  13.  
  14.         threading.Thread.__init__(self, name = nombreHilo)
  15.         self.cant=cant
  16.         self.condicion=condicion
  17.         self.asientos=asientos
  18.        
  19.     def run(self):
  20.         #Reserva
  21.        
  22.         for i in range(self.cant):
  23.             self.condicion.acquire()
  24.             time.sleep(random.randrange(5))
  25.             a=random.randint(1,1000)-1
  26.             self.asientos[a]=False
  27.            
  28.             print ("Se reservó el asiento "+ str(a))
  29.        
  30.         self.condicion.notify()
  31.         self.condicion.release()
  32.         time.sleep(random.randrange(2))
  33.  
  34. class Consulta(threading.Thread):
  35.    
  36.     def __init__(self, nombreHilo, asientos, condicion, cant):
  37.  
  38.         threading.Thread.__init__(self, name = nombreHilo)
  39.         self.cant=cant
  40.         self.condicion=condicion
  41.         self.asientos=asientos
  42.                
  43.     def run(self):
  44.         self.condicion.acquire()
  45.        
  46.         asientos2=self.asientos
  47.         print("prueba")
  48.        
  49.         list.count(x)  #asientos disponibles
  50.                
  51.         time.sleep(random.randrange(2))
  52.         self.condicion.wait()
  53.         self.condicion.release()
  54.  
  55. condicion = threading.Condition()
  56. asi_vuelo = []
  57. for v in range(1000):           #Armando el avion
  58.     asi_vuelo.append(True)
  59.  
  60. #vuelo = BufferCircular()               #Aca está mi problema
  61. lector = Consulta("Consulta", asi_vuelo, condicion, 20)
  62. escritor = Reserva("Reserva", asi_vuelo, condicion, 20)
  63.  
  64. lector.start()
  65. escritor.start()
  66.  
  67. lector.join()
  68. escritor.join()

Última edición por pabloryser; 15/05/2015 a las 12:50 Razón: Edito. Olvide el enunciado
  #2 (permalink)  
Antiguo 16/05/2015, 01:52
 
Fecha de Ingreso: mayo-2015
Mensajes: 15
Antigüedad: 9 años, 6 meses
Puntos: 0
Respuesta: Problema con hilos

Lo hice... CASI!!!
Está separado en clases y funcionando mas o menos.
Hice el avión mas chico para verificar datos repetidos que deberían obviarse con un while en la linea 18 de la clase reserva.
El tema es que Reserva el asiento 15 por ejemplo y en la lista de ocupados me guarda un 16, y a partir de ahi todos los numeros tienen una pequeña variación, no se cual podría ser el problema (Clase vuelo linea 13).

Ayuda por favor, he plantado culo en asiento y avancé bastante, pero parece que "ALGO" no estoy viendo bien.

Desde ya muchas gracias.

Edito: Ya di con el error. En la linea 13 de la clase Vuelo paso a la nueva lista el orden del valor y no el valor en si y difieren en primera instancia en 1 (aumenta a medida q voy sacando). Todavia tengo que resolverlo.

Código Python(main):
Ver original
  1. # Simular con hilos un sistema de reservación de vuelos. Las personas pueden consultar y reservar vuelos.
  2. # Hacer la sincronización con múltiples personas accediendo al registro de vuelos.
  3. # Cuando se reserva no se puede consultar y viceversa. Lanzar 20 hilos
  4. # 1000 lugares en el avion.
  5.  
  6. from Buffer import Vuelo                     #Buffer, Ev_lector y Ev_escritor son los modulos
  7. from Ev_lector import Consulta
  8. from Ev_escritor import Reserva
  9.  
  10. vuelo = Vuelo()            
  11. lector = Consulta("Consulta", vuelo, 20)
  12. escritor = Reserva("Reserva", vuelo, 20)
  13.  
  14. lector.start()
  15. escritor.start()
  16.  
  17. lector.join()
  18. escritor.join()

Código Python(Clase Reserva):
Ver original
  1. import threading
  2. import random
  3. import time
  4.  
  5. class Reserva(threading.Thread):
  6.    
  7.     def __init__(self, nombreHilo, asientos, cant):
  8.  
  9.         threading.Thread.__init__(self, name=nombreHilo)
  10.         self.cant=cant
  11.         self.asientos=asientos
  12.        
  13.     def run(self):
  14.         #Reserva
  15.         for i in range(self.cant):
  16.             time.sleep(random.randrange(3))
  17.             a=random.randint(1,100)
  18.             while (self.asientos.vuelo.count(a)==0):
  19.                 a=random.randint(1,100)
  20.             self.asientos.set(a)
  21.             print ("El hilo "+str(self.name)+" reserva el asiento "+ str(a))

Código Python(Clase Consulta):
Ver original
  1. import threading
  2. import random
  3. import time
  4.  
  5. class Consulta(threading.Thread):
  6.    
  7.     def __init__(self, nombreHilo, asientos, cant):
  8.  
  9.         threading.Thread.__init__(self, name = nombreHilo)
  10.         self.cant=cant
  11.         self.asientos=asientos
  12.                
  13.     def run(self):
  14.                
  15.         for i in range(self.cant):
  16.             time.sleep(random.randrange(3))
  17.             #a=self.asientos.ocup
  18.            
  19.             print("La lista de asientos ocupados es la siguiente: \n" + str(self.asientos.get())+"\n")

Código Python(Clase Vuelo):
Ver original
  1. import threading
  2.  
  3. class Vuelo:
  4.  
  5.     def __init__(self):
  6.         self.vuelo = []
  7.         for v in range(1,101):
  8.             self.vuelo.append(v)
  9.         print(str(self.vuelo))
  10.         self.ocup=[]
  11.                    
  12.     def set(self,asiento):
  13.         self.ocup.append(self.vuelo.pop(asiento))
  14.        
  15.     def get(self):
  16.         asi_oc=self.ocup
  17.         return asi_oc

Última edición por pabloryser; 16/05/2015 a las 08:29 Razón: Error detectado
  #3 (permalink)  
Antiguo 16/05/2015, 13:52
 
Fecha de Ingreso: mayo-2015
Mensajes: 15
Antigüedad: 9 años, 6 meses
Puntos: 0
Respuesta: Problema con hilos

Ahora si, funcionando.
No se si estará bien implementado el tema de los hilos, pero funciona bien.
Se los dejo por si a alguien le sirve.
Si alguien tiene algo mas para aportar bienvenido sea!!
Gracias por leer esto jeje.

Código Python:
Ver original
  1. # Simular con hilos un sistema de reservación de vuelos. Las personas pueden consultar y reservar vuelos.
  2. # Hacer la sincronización con múltiples personas accediendo al registro de vuelos.
  3. # Cuando se reserva no se puede consultar y viceversa. Lanzar 20 hilos
  4. # 1000 lugares en el avion.
  5.  
  6. from Buffer import Vuelo                    #<-- Buffer, Ev_lector y Ev_escritor son los nombres de los modulos
  7. from Ev_lector import Consulta
  8. from Ev_escritor import Reserva
  9.  
  10. cant_asi=1000
  11. cant_consultas=20
  12. cant_reservas=20
  13. vuelo = Vuelo(cant_asi)            
  14. lector = Consulta("Consulta", vuelo, cant_consultas)
  15. escritor = Reserva("Reserva", vuelo, cant_reservas)
  16.  
  17. lector.start()
  18. escritor.start()
  19.  
  20. lector.join()
  21. escritor.join()
  22.  
  23. asi_oc=vuelo.get()
  24. print("Lista final de asienos reservados:\n{0}".format(str(asi_oc)))

Código Python:
Ver original
  1. import threading
  2.  
  3. class Vuelo:
  4.  
  5.     def __init__(self, cant):
  6.         self.vuelo = []
  7.         self.cant=cant
  8.         for v in range(1,self.cant+1):
  9.             self.vuelo.append(v)
  10.         #print(str(self.vuelo)) <--- Era para verificar el armado de la lista de asientos
  11.         self.ocup=[]
  12.                    
  13.     def set(self,asiento):
  14.         self.ocup.append(asiento)
  15.         self.vuelo.remove(asiento)
  16.     def get(self):
  17.         asi_oc=self.ocup
  18.         asi_oc.sort()
  19.         return asi_oc
  20.     def get_cant(self):
  21.         par=self.cant
  22.         return par

Código Python:
Ver original
  1. import threading
  2. import random
  3. import time
  4.  
  5. class Reserva(threading.Thread):
  6.    
  7.     def __init__(self, nombreHilo, asientos, cant):
  8.  
  9.         threading.Thread.__init__(self, name=nombreHilo)
  10.         self.cant=cant
  11.         self.asientos=asientos
  12.        
  13.     def run(self):
  14.         #Reserva
  15.         for i in range(self.cant):
  16.             time.sleep(random.randrange(5))
  17.             a=random.randint(1,self.asientos.get_cant())
  18.             while (self.asientos.vuelo.count(a)==0):
  19.                 a=random.randint(1,self.asientos.get_cant())
  20.             self.asientos.set(a)
  21.             print ("El hilo "+str(self.name)+" reserva el asiento "+ str(a))

Código Python:
Ver original
  1. import threading
  2. import random
  3. import time
  4.  
  5. class Consulta(threading.Thread):
  6.    
  7.     def __init__(self, nombreHilo, asientos, cant):
  8.  
  9.         threading.Thread.__init__(self, name = nombreHilo)
  10.         self.cant=cant
  11.         self.asientos=asientos
  12.                
  13.     def run(self):
  14.                
  15.         for i in range(self.cant):
  16.             time.sleep(random.randrange(5))
  17.             asi_oc=self.asientos.get()
  18.             print("El hilo {1} consulta la lista de asientos ocupados y es la siguiente: \n {0} \n".format(str(asi_oc), str(self.name)))
  #4 (permalink)  
Antiguo 20/05/2015, 10:24
Avatar de nup_  
Fecha de Ingreso: noviembre-2010
Mensajes: 265
Antigüedad: 14 años
Puntos: 32
Respuesta: Problema con hilos

Desgraciadamente no es tan sencillo.
"vuelo" es un recurso compartido por 2 hilos, por tanto debes sincronizar su acceso.
Lee un poco acerca de sincronización de hilos en python:
http://mundogeek.net/archivos/2008/0...ads-en-python/

Un poco de teoría no te vendría mal tampoco:
http://es.wikipedia.org/wiki/Sem%C3%...maci%C3%B3n%29

Nup_
  #5 (permalink)  
Antiguo 20/05/2015, 12:05
 
Fecha de Ingreso: mayo-2015
Mensajes: 15
Antigüedad: 9 años, 6 meses
Puntos: 0
Respuesta: Problema con hilos

Si, estaba al tanto de que no estaba sincronizado (pero andaba). Me falta el "adquire". Pero lo hice con la contras de que 1- entendia poco 2-material que encontraba estaba en ingles 3-problema de versiones cuando encontraba algo .
Voy a ver eso que me pusiste, muchas gracias.

Última edición por pabloryser; 25/05/2015 a las 20:46
  #6 (permalink)  
Antiguo 25/05/2015, 20:46
 
Fecha de Ingreso: mayo-2015
Mensajes: 15
Antigüedad: 9 años, 6 meses
Puntos: 0
Respuesta: Problema con hilos

AHORA SI RESUELTO, SINCRONIZADO Y FUNCIONANDO (por si sirve de ayuda a alguien)

Código Python:
Ver original
  1. #Este es el main
  2.  
  3. # Simular con hilos un sistema de reservación de vuelos. Las personas pueden consultar y reservar vuelos.
  4. # Hacer la sincronización con múltiples personas accediendo al registro de vuelos.
  5. # Cuando se reserva no se puede consultar y viceversa. Lanzar 20 hilos
  6. # 1000 lugares en el avion.
  7.  
  8. from Buffer import Vuelo
  9. from Ev_lector import Consulta
  10. from Ev_escritor import Reserva
  11.  
  12. cant_asi=20
  13. cant_consultas=5
  14. cant_reservas=5
  15. vuelo = Vuelo(cant_asi)            
  16. lector = Consulta("Consulta", vuelo, cant_consultas)
  17. escritor = Reserva("Reserva", vuelo, cant_reservas)
  18.  
  19. lector.start()
  20. escritor.start()
  21.  
  22. lector.join()
  23. escritor.join()
  24.  
  25. asi_oc=vuelo.get("MAIN")
  26. print("Lista final de asienos reservados:\n{0}".format(str(asi_oc)))

Código Python:
Ver original
  1. # "Ev_lector"
  2.  
  3. import threading
  4. import random
  5. import time
  6.  
  7. class Consulta(threading.Thread):
  8.    
  9.     def __init__(self, nombreHilo, asientos, cant):
  10.  
  11.         threading.Thread.__init__(self, name = nombreHilo)
  12.         self.cant=cant
  13.         self.asientos=asientos
  14.                
  15.     def run(self):
  16.                
  17.         for i in range(self.cant):
  18.             #time.sleep(random.randrange(5))
  19.             asi_oc=self.asientos.get(self.name)
  20.             print("El hilo {1} consulta la lista de asientos ocupados y es la siguiente: \n {0} \n".format(str(asi_oc), str(self.name)))

Código Python:
Ver original
  1. # "Ev_escritor"
  2.  
  3. import threading
  4. import random
  5. import time
  6.  
  7. class Reserva(threading.Thread):
  8.    
  9.     def __init__(self, nombreHilo, asientos, cant):
  10.  
  11.         threading.Thread.__init__(self, name=nombreHilo)
  12.         self.cant=cant
  13.         self.asientos=asientos
  14.        
  15.     def run(self):
  16.         #Reserva
  17.         for i in range(self.cant):
  18.             #time.sleep(random.randrange(5))
  19.             a=random.randint(1,self.asientos.get_cant())
  20.             while (self.asientos.vuelo.count(a)==0):
  21.                 a=random.randint(1,self.asientos.get_cant())
  22.             self.asientos.set(a, self.name)
  23.             print ("El hilo "+str(self.name)+" reserva el asiento "+ str(a))

Código Python:
Ver original
  1. # "Buffer"
  2.  
  3. import threading
  4. import time
  5. import random
  6.  
  7. class Vuelo:
  8.  
  9.     def __init__(self, cant):
  10.         self.vuelo = []
  11.         self.cant=cant
  12.         for v in range(1,self.cant+1):
  13.             self.vuelo.append(v)
  14.         #print(str(self.vuelo)) <--- Era para verificar el armado de la lista de asientos
  15.         self.ocup=[]
  16.         self.candado = threading.Lock()
  17.                    
  18.     def set(self, asiento, nombre):
  19.         self.candado.acquire()
  20.         print("-*"*25)
  21.         print("Toma control "+nombre)            #Para verificar que no se pise el hilo
  22.         time.sleep(random.randrange(5))
  23.         self.ocup.append(asiento)
  24.         self.vuelo.remove(asiento)
  25.         print("Suelta control "+nombre)
  26.         self.candado.release()
  27.        
  28.     def get(self, nombre):
  29.         self.candado.acquire()
  30.         print("-"*50)
  31.         print("Toma control "+nombre)            #Para verificar que no se pise el hilo
  32.         asi_oc=self.ocup
  33.         asi_oc.sort()
  34.         print("Suelta control "+nombre)
  35.         self.candado.release()
  36.         return asi_oc
  37.        
  38.     def get_cant(self):
  39.         par=self.cant
  40.         return par

Etiquetas: funcion, hilos, programa
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 11:05.