Veamos ahora dos hilos en los cuales podemos dar alternancia, el principal escribe “X” y el secundario “Y”, 1000 veces cada uno.
Notas: podemos ralentizar la ejecución con time.sleep(segundos). end=”” se coloca para evitar el salto de línea final que viene por defecto con print.
import threading
def escribeY():
for i in range(1000):
print ("y", end="",flush=True)
return
print ("INICIO")
t = threading.Thread(target=escribeY)
t.start()
for i in range(1000):
print ("X", end="",flush=True)
Crea un programa en Python donde un hilo escriba por pantalla un punto «.» cada segundo, mientras otro segundo hilo escriba una raya (símbolo guión) «-» cada dos segundos. El programa debe terminar cuando hayan 100 puntos y 50 rayas. Usa la funcion
time.sleep(1)
si quieres que espere un segundo.
Utiliza el entrono JupyterLab jupyter-lab
Compara con tus compañeros los resultados cuando incluyes la opción flush y cuando no se utiliza e intenta encontrarle una explicación
Crea un proyecto Git «02-thread» y sube tu aplicación al repositorio de clase.. Tu proyecto debe incluir el fichero README en formato Markdown con el resultado de la ejecución y una explicación del funcionamiento.
Ejecuta | Usar sólo en caso de emergencia o una vez hayas resuelto el ejercicio.
Todos los hilos ven las variables accesibles desde el ámbito en el que se han creado. Si por ejemplo tenemos un método que puede ser invocado por cualquier hilo pero sólo queremos que lo ejecute uno (el primero que lo invoque). Podríamos tener una variable “Realizado” inicializada a false que luego una vez ejecutado un determinado proceso se podrá a true. De esta forma evitaremos que se ejecute por segunda vez.
import threading
import time
import random
def tareaUno():
global Realizado
#time.sleep (random.random())
if not Realizado:
print("Tarea realizada")
Realizado = True
return
Realizado = False
t = threading.Thread(target=tareaUno)
t.start()
tareaUno()
time.sleep(1)
Compara con tus compañeros los resultados y comenta si ves correcto el funcionamiento. Descomenta la línea
#time.sleep (random.random())
y vuelve a probar el código unas cuantas veces.
Por ejemplo después de ejecutar 3 veces nos aparece dos veces el mensaje una vez y una vez con dos mensajes.
Para solucionar este inconveniente se utilizará el concepto de REGIÓN CRÍTICA que verremos más adelante.
Veamos el código si en vez dos hilos creamos 50 hilos que acceden a la misma variable.
import threading
import time
import random
def tareaUno():
global Done
time.sleep (random.random())
if not Done:
print("Tarea realizada")
Done = True
else :
print ("tarea NO REALIZADA")
return
Done = False
hilos = list()
for i in range(50):
t = threading.Thread(target=tareaUno)
hilos.append(t)
t.start()
tareaUno()
time.sleep(1)
Simulamos ciertos retrasos y vemos que hasta que los otros hilos comprueban el estado de la variable esta mantiene su valor durante unas pocas centésimas.
import threading
import time
import random
def tareaUno():
global Done
time.sleep (random.random())
if not Done:
print("Tarea realizada")
time.sleep(0.12)
Done = True
else :
print ("tarea NO REALIZADA")
time.sleep(0.05)
return
Done = False
hilos = list()
for i in range(50):
t = threading.Thread(target=tareaUno)
hilos.append(t)
t.start()
tareaUno()
time.sleep(1)
Modifica el código anteriror para que cada cierto tiempo (usa la distribución de la campana de Gauss) un hilo llame a una función que desbloquee la variable global y permita imprimir «Tarea realizada» por alguno de los 50 hilos que se genera.
Crea un proyecto Git «03-thread» y sube tu aplicación al repositorio de clase.. Tu proyecto debe incluir el fichero README en formato Markdown con el resultado de la ejecución y justificación del funcionamiento.
Ejecuta | Usar sólo en caso de emergencia o una vez hayas resuelto el ejercicio.