Un problema típico en paralelismo es la sincronización de un proceso productor y otro consumidor. Uno de los hilos produce algún tipo de elemento mientras que el otro los consume, ambos hilos deberían estar funcionando en paralelo.
El problema del productor vendrá dado por las limitaciones que tenga el objeto, buffer o lista que tenga para guardar dichos elementos.
El problema del consumidor que intente consumir un elemento que todavía no existe.
En el ejemplo usamos los métodos full()
y empty()
sobre una cola para poder descartar, insertar o sacar elementos. La solución correcta será la de dejar sus pendidos los hilos, en lugar de estar constantemente comprobando full()
/empty()
.
import threading
import time
import logging
import random
import queue
logging.basicConfig(level=logging.DEBUG,
format='(%(threadName)-9s) %(message)s',)
BUF_SIZE = 10
q = queue.Queue(BUF_SIZE)
class HiloProductor(threading.Thread):
def __init__(self,name=None):
super(HiloProductor,self).__init__()
self.name = name
def run(self):
while True:
if not q.full():
item = random.randint(1,10)
q.put(item)
logging.debug('Insertando "' + str(item)
+ '" : ' + str(q.qsize()) + ' elementos en la cola')
time.sleep(random.random())
return
class HiloConsumidor(threading.Thread):
def __init__(self,name=None):
super(HiloConsumidor,self).__init__()
self.name = name
return
def run(self):
while True:
if not q.empty():
item = q.get()
logging.debug('Sacando "' + str(item)
+ '" : ' + str(q.qsize()) + ' elementos en la cola')
time.sleep(random.random())
return
p = HiloProductor(name='productor')
p2 = HiloProductor(name='productor2')
c = HiloConsumidor(name='consumidor')
p.start()
p2.start()
c.start()
Sobre este programa se puede probar a poner un segundo productor “p2=HiloProductor(name=’productor2′” o un segundo consumidor.
(productor) Insertando "8" : 1 elementos en la cola (productor2) Insertando "6" : 2 elementos en la cola (consumidor) Sacando "8" : 1 elementos en la cola (consumidor) Sacando "6" : 0 elementos en la cola (productor) Insertando "2" : 1 elementos en la cola (productor2) Insertando "10" : 2 elementos en la cola (consumidor) Sacando "2" : 1 elementos en la cola (productor2) Insertando "5" : 2 elementos en la cola (productor) Insertando "1" : 3 elementos en la cola (productor2) Insertando "7" : 4 elementos en la cola (consumidor) Sacando "10" : 3 elementos en la cola (productor2) Insertando "1" : 4 elementos en la cola (productor) Insertando "7" : 5 elementos en la cola (productor2) Insertando "7" : 6 elementos en la cola (consumidor) Sacando "5" : 5 elementos en la cola (productor2) Insertando "2" : 6 elementos en la cola (consumidor) Sacando "1" : 5 elementos en la cola (productor) Insertando "2" : 6 elementos en la cola (productor2) Insertando "10" : 7 elementos en la cola (productor) Insertando "6" : 8 elementos en la cola (consumidor) Sacando "7" : 7 elementos en la cola (productor2) Insertando "9" : 8 elementos en la cola (productor) Insertando "10" : 9 elementos en la cola (productor2) Insertando "1" : 10 elementos en la cola (consumidor) Sacando "1" : 9 elementos en la cola (productor) Insertando "8" : 10 elementos en la cola (consumidor) Sacando "7" : 9 elementos en la cola (productor2) Insertando "10" : 10 elementos en la cola (consumidor) Sacando "7" : 9 elementos en la cola (productor) Insertando "6" : 10 elementos en la cola ...
Modifica el código donde se controle mediante sincronismo los hilos productores y consumidores: