1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import threading import queue import time import random # Crear una cola con una capacidad máxima q = queue.Queue(maxsize=10) # Función del productor def productor(): for i in range(20): item = random.randint(1, 100) q.put(item) print(f'Productor produjo: {item}') time.sleep(random.uniform(0.1, 1)) q.put(None) # Señal para los consumidores de que se terminó la producción # Función del consumidor def consumidor(): while True: item = q.get() if item is None: break print(f'Consumidor consumió: {item}') time.sleep(random.uniform(0.1, 1)) # Crear los hilos de productor y consumidor hilo_productor = threading.Thread(target=productor) hilo_consumidor = threading.Thread(target=consumidor) # Iniciar los hilos # Ambos hilos comienzan su ejecución de forma concurrente, es decir, ambos pueden estar ejecutándose al mismo tiempo, intercalando sus operaciones según la planificación del sistema operativo y el intérprete de Python. hilo_productor.start() hilo_consumidor.start() # Esperar a que los hilos terminen hilo_productor.join() hilo_consumidor.join() print('Producción y consumo completados.') |
Este código hace lo siguiente:
- Importaciones: Importa los módulos necesarios (
threading
,queue
,time
, yrandom
). - Cola: Crea una cola
q
con una capacidad máxima de 10 elementos. - Productor: Define la función del productor que produce 20 elementos aleatorios y los coloca en la cola. Después de producir todos los elementos, el productor coloca
None
en la cola para señalar a los consumidores que ha terminado. - Consumidor: Define la función del consumidor que consume los elementos de la cola. Si el consumidor encuentra
None
, sale del bucle y termina. - Hilos: Crea e inicia los hilos para el productor y el consumidor.
- Sincronización: Espera a que ambos hilos terminen utilizando
join
.
¿Por qué funciona correctamente?
El uso de la cola (queue.Queue
) maneja la sincronización entre el productor y el consumidor de manera automática:
- Bloqueo y Desbloqueo Automático: La cola se encarga de bloquear el productor si la cola está llena y el consumidor si la cola está vacía, gestionando así el flujo de manera segura y evitando que se ejecuten incorrectamente múltiples hilos a la vez.
- Sin Necesidad de Locks Adicionales: No es necesario utilizar locks adicionales (
threading.Lock
) porque la cola maneja la sincronización interna.