Anuncios

Bienvenidos sean a este post, hoy veremos como son las comunicaciones en un thread.

Anuncios

Para este caso primero veremos como realizar las comunicaciones y despues como enviar eventos, comencemos con el primer caso a traves de un ejemplo, primero importemos los modulos necesarios:

>>> import threading
>>> from queue import Queue
Anuncios

Aqui la que nos interesa mas es Queue que sera la encargada de hacer la magia, lo siguiente sera crear un objeto:

>>> CENTINELA = object()
Anuncios

Este es un objeto simple que lo usaremos para que sirva como señal para indicar que pase de un thread a otro pero de esto hablaremos mas adelante, para nuestro siguiente paso definiremos una nueva funcion:

>>> def productor(e, n):
...     a, b = 0, 1
...     while a <= n:
...             e.put(a)
...             a, b = b, a + b
...     e.put(CENTINELA)
... 
>>>
Anuncios

Esta funcion recibe dos atributos, uno de tipo Queue y un valor, luego definiremos dos variables llamadas a y b, mientras a sea menor o igual a n hara un bucle con while y en este agregaremos al Queue el valor de a, lo siguiente es trabajar como hicimos con la funcion Fibo que vimos en este post, donde reemplazaremos el valor de a con b y el de b con la suma de ambos, por ultimo pasaremos a Queue el objeto CENTINELA el cual informara a la siguiente funcion que este esta preparado, pasemos a definir la siguiente funcion:

>>> def consumidor(e):
...     while True:
...             num = e.get()
...             e.task_done()
...             if num is CENTINELA:
...                     break
...             print(f'Consegui el numero {num}')
... 
>>>
Anuncios
Anuncios

Esta funcion recibe el objeto de Queue, mientras sea True ejecutara la misma, en num almacenaremos lo almacenado en el Queue informado, luego usaremos a task_done para verificar que todo ha sido procesado, lo siguiente es un condicional donde verifica si num es igual a CENTINELA y en caso de ser verdadero llama a break para salir del bucle lo siguiente sera mostrar el valor de num mientras corra el bucle, con esto tenemos las dos funciones definidas ahora vamos a implementarlas, lo siguiente sera crear el objeto para el Queue:

>>> e = Queue()
Anuncios

Lo siguiente sera crear los dos threads para nuestras funciones:

>>> cns = threading.Thread(target=consumidor, args=(e, ))
>>> prd = threading.Thread(target=productor, args=(e, 35))
Anuncios

Observen como pasamos el objeto creado para el Queue como argumento, en el caso del consumidor solamente el Queue y en el productor al Queue y el valor que servira de limite, lo siguiente sera iniciar ambos threads:

>>> cns.start()
>>> prd.start()
Anuncios

Cuando iniciemos nuestro thread del consumidor no sucedera nada pero esta esperando lo que genere la otra funcion, cuando iniciemos el productor sucedera lo siguiente:

Consegui el numero 0
Consegui el numero 1
Consegui el numero 1
Consegui el numero 2
Consegui el numero 3
Consegui el numero 5
Consegui el numero 8
Consegui el numero 13
Consegui el numero 21
Consegui el numero 34
>>>
Anuncios

Como pueden ver funciono hasta superar el valor de 35, por ultimo lo que debemos hacer es usar el join para liberar todos los elementos que hayan sido procesados:

>>> e.join()
Anuncios

Esta es una forma de poder pasar informacion entre dos threads, ahora vamos a pasar al siguiente tema.

Anuncios

Enviando eventos

Para este caso vamos a escribir otro ejemplo, comenzaremos importando solamente el modulo para los threads:

>>> import threading
Anuncios

Lo siguiente sera definir una funcion llamada inicio:

>>> def inicio():
...     print('Iniciando evento...')
...     evento.set()
... 
>>>
Anuncios

Este es una funcion simple que mostrara un mensaje de inicio de un evento, y luego estableceremos el evento por medio de set, nuestros siguiente paso sera definir otra funcion:

>>> def escuchar():
...     evento.wait()
...     print('Evento ha sido iniciado')
... 
>>>
Anuncios

Esta nueva funcion lo primero que hara sera esperar que el evento haya sido iniciado o establecido y despues mostrara un mensaje haciendo referencia a esto, nuestro siguiente paso sera crear el evento en si:

>>> evento = threading.Event()
Anuncios

Es simplemente crear el objeto que mencionamos antes con el metodo Event de threading, despues crearemos los dos threads para las funciones:

>>> t1 = threading.Thread(target=inicio)
>>> t2 = threading.Thread(target=escuchar)
Anuncios

Tan simple como hasta ahora donde cada target es una de las funciones antes definidas, nuestro siguiente paso sera iniciar el thread llamado t2:

>>> t2.start()
Anuncios

Este thread no hara nada porque esta esperando que evento sea establecido y como todavia no lo hicimos se quedara ahi cargado y esperando, el siguiente paso sera iniciar a t1:

>>> t1.start()
Anuncios

Y aqui si sucedera la magia, veamos la salida:

Iniciando evento...
>>> Evento ha sido iniciado
Anuncios

En este caso vemos la salida de la funcion inicio pero automaticamente se mostrara la funcion escuchar porque al iniciarse evento este puede seguir con sus instrucciones.

Anuncios

En resumen, hoy hemos visto como se comunican entre threads, hemos visto como lo hace a traves de un objeto que actua como señal, luego hemos visto como podemos utilizar eventos entre distintos threads para esperar que uno trabaje con el otro, espero les haya sido util sigueme en tumblr, Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Anuncios
pp258

Donación

Es para mantenimento del sitio, gracias!

$1.50