Profesor Miguel Cantillana
INS240 – Lenguajes de Programación
Ingeniería en Computación e Informática
Semestre 2017-1
Sincronización de Thread
import threading
total = 0
def acumula5():
global total
contador = 0
hilo_actual = threading.current_thread().getName()
while contador < 20:
print('Esperando para bloquear', hilo_actual)
bloquea.acquire()
try:
contador = contador + 1
total = total + 5
print('Bloqueado por', hilo_actual, contador)
print('Total', total)
finally:
print('Liberado bloqueo por', hilo_actual)
bloquea.release()
bloquea = threading.Lock()
hilo1 = threading.Thread(name='h1', target=acumula5)
hilo2 = threading.Thread(name='h2', target=acumula5)
hilo1.start()
hilo2.start()
thread_14.py
import threading
def acumula5():
global total
contador = 0
hilo_actual = threading.current_thread().getName()
num_intentos = 0
while contador < 20:
lo_consegui = bloquea.acquire(blocking=False)
try:
if lo_consegui:
contador = contador + 1
total = total + 5
print('Bloqueado por', hilo_actual, contador)
print('Total', total,hilo_actual)
else:
num_intentos+=1
print('Número de intentos de bloqueo',
num_intentos,
'hilo',
hilo_actual,
bloquea.locked())
print(hilo_actual,'Hacer otro trabajo')
finally:
if lo_consegui:
print('Liberado bloqueo por', hilo_actual)
bloquea.release()
total = 0
bloquea = threading.Lock()
hilo1 = threading.Thread(name='h1', target=acumula5)
hilo2 = threading.Thread(name='h2', target=acumula5)
hilo1.start()
hilo2.start()
thread_15.py
La forma más fácil de hacer que un hilo espere a que otro hilo le avise es por medio de Event.
import threading, random, logging
logging.basicConfig( level=logging.DEBUG,
format='[%(levelname)s] - %(threadName)-10s : %(message)s')
def gen_pares():
num_pares = 0
logging.debug('Numeros pares: ')
while num_pares < 25:
numero = random.randint(1, 10)
resto = numero % 2
if resto == 0:
num_pares +=1
logging.debug('Numero par %s: ',str(numero))
def contar():
contar = 0
nom_hilo = threading.current_thread().getName()
# print(nom_hilo, "en espera")
logging.debug("En espera")
estado = evento.wait()
while contar < 25:
contar+=1
# print(nom_hilo, ':', contar)
logging.debug('contar: %d',contar)
evento = threading.Event()
hilo1 = threading.Thread(name='h1', target=contar)
hilo2 = threading.Thread(name='h2', target=contar)
hilo1.start()
hilo2.start()
logging.debug('Obteniendo 25 números pares...')
gen_pares()
logging.debug('Ya se han obtenido')
evento.set()
thread_16.py
import threading
def avanza(evento):
ciclo = 0
valor = 0
while valor < 20:
estado = evento.wait()
if estado:
ciclo+=1
valor+=1
print('avanza', valor)
if ciclo == 10 and hilo2.isAlive():
evento.clear()
ciclo = 0
print('avanza: ha finalizado')
def retrocede(evento, tiempo):
ciclo = 0
valor = 21
while valor > 1:
estado = evento.wait(tiempo)
if not estado:
ciclo+=1
valor-=1
print('retrocede', valor)
if ciclo == 5 and hilo1.isAlive():
evento.set()
ciclo = 0
print('retrocede: ha finalizado')
evento = threading.Event()
hilo1 = threading.Thread(target=avanza,
args=(evento,),)
hilo2 = threading.Thread(target=retrocede,
args=(evento, 0.5),)
hilo1.start()
hilo2.start()
thread_17.py
import threading
import time
import logging
logging.basicConfig(level=logging.DEBUG,
format='(%(threadName)-9s) %(message)s',)
def consumer(cv):
logging.debug('Consumer thread started ...')
# with cv:
cv.acquire()
logging.debug('Consumer waiting ...')
cv.wait()
logging.debug('Consumer consumed the resource')
cv.release()
def producer(cv):
logging.debug('Producer thread started ...')
# with cv:
cv.acquire()
logging.debug('Making resource available')
logging.debug('Notifying to all consumers')
cv.notifyAll()
cv.release()
if __name__ == '__main__':
condition = threading.Condition()
cs1 = threading.Thread(name='consumer1', target=consumer, args=(condition,))
cs2 = threading.Thread(name='consumer2', target=consumer, args=(condition,))
pd = threading.Thread(name='producer', target=producer, args=(condition,))
cs1.start()
time.sleep(2)
cs2.start()
time.sleep(2)
pd.start()
thread_19.py
# -*- coding: utf-8 -*-
import threading, random, math
def funcion1(condicion):
global lista
print(threading.current_thread().name,
'esperando a que se generen los números')
condicion.acquire()
condicion.wait()
print('Elementos:', len(lista), threading.current_thread().name)
print('Suma total:', math.fsum(lista),threading.current_thread().name)
condicion.release()
def funcion2(condicion):
global lista
print(threading.current_thread().name,
'generando números')
condicion.acquire()
for numeros in range(1, 1001):
entero = random.randint(1,100)
lista.append(entero)
print('Ya hay 1000 números')
condicion.notifyAll()
condicion.release()
lista = []
condicion = threading.Condition()
hilo1 = threading.Thread(name='hilo1', target=funcion1,
args=(condicion,))
hilo2 = threading.Thread(name='hilo2', target=funcion2,
args=(condicion,))
hilo1.start()
hilo2.start()
thread_18_1.py
# -*- coding: utf-8 -*-
import threading, random, math
def funcion1(condicion):
global lista
print(threading.current_thread().name,
'esperando a que se generen los números')
with condicion:
condicion.wait()
print('Elementos:', len(lista), threading.current_thread().name)
print('Suma total:', math.fsum(lista),threading.current_thread().name)
def funcion2(condicion):
global lista
print(threading.current_thread().name,
'generando números')
with condicion:
for numeros in range(1, 1001):
entero = random.randint(1,100)
lista.append(entero)
print('Ya hay 1000 números')
condicion.notifyAll()
lista = []
condicion = threading.Condition()
hilo1 = threading.Thread(name='hilo1', target=funcion1,
args=(condicion,))
hilo2 = threading.Thread(name='hilo2', target=funcion2,
args=(condicion,))
hilo1.start()
hilo2.start()
thread_18.py
#!/usr/bin/python
import threading
cond = threading.Condition()
class Cliente (threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while True:
cond.acquire()
cond.wait()
mesa.pop()
cond.notify()
cond.release()
class Cosinero(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
while True:
cond.acquire()
if len(mesa) != 0: cond.wait()
mesa.append("Torta de frutillas ")
cond.notify()
cond.release()
print "El bar"
mesa = []
cliente = Cliente()
cosinero = Cosinero()
cliente.start()
cosinero.start()
# while True:
# print mesa
thread_20.py
import threading
import time
def descargando(semaforo):
global activas
nombre = threading.current_thread().getName()
print('Esperando para descargar:', nombre)
with semaforo:
activas.append(nombre)
print('Descargas activas', activas)
print('...Descargando...', nombre)
time.sleep(0.1)
activas.remove(nombre)
print('Descarga finalizada', nombre)
NUM_DESCARGAS_SIM = 3
activas = []
semaforo = threading.Semaphore(NUM_DESCARGAS_SIM)
for indice in range(1,6):
hilo = threading.Thread(target=descargando,
name='D' + str(indice),
args=(semaforo,),)
hilo.start()
thread_22.py
import threading, random, math
def funcion1(barrera):
nom_hilo = threading.current_thread().name
print(nom_hilo,
'Esperando con',
barrera.n_waiting,
'hilos más')
numero = random.randint(1,10)
ident = barrera.wait()
print(nom_hilo,
'Ejecutando después de la espera',
ident)
print('factorial de',
numero,
'es',
math.factorial(numero),nom_hilo)
NUM_HILOS = 5
barrera = threading.Barrier(NUM_HILOS)
hilos = [threading.Thread(name='hilo-%s' % i,
target=funcion1,
args=(barrera,),
) for i in range(NUM_HILOS)]
for hilo in hilos:
print(hilo.name, 'Comenzando ejecución')
hilo.start()
thread_21.py
try:
ident = barrera.wait()
except threading.BrokenBarrierError:
print(nom_hilo, 'Cancelando')
else:
print('Ejecutando después de la espera', ident)