Barreras en Python

Es un método de sincronización. Una barrera para un grupo de hilos o procesos significa que todos los que implementen esta barrera deberán parar en ese punto sin poder ejecutar las siguientes líneas de código hasta que todos los restantes hilos/procesos hayan alcanzado esta barrera.

Construcciones barrera clásicas definen el conjunto de procesos / hilos de participar de forma estática. Esto suele hacerse, ya sea al inicio del programa o cuando una barrera como el Pthreads barrera se crea una instancia. Esto restringe las posibles aplicaciones para las que se pueden utilizar barreras.

Apoyar paradigmas de programación más dinámicos como tenedor / unirse paralelismo, los conjuntos de los participantes tienen que ser dinámicos. Por lo tanto, necesita el conjunto de procesos / hilos que participan en una operación de barrera para ser capaz de cambiar con el tiempo. X10 introdujo el concepto de los relojes para tal fin, que proporcionan una barrera dinámica semántica. Sobre la base de los relojes, sincronizadores . Se han propuesto para añadir aún más flexibilidad para la sincronización de barrera. Con sincronizadores es posible expresar dependencias de datos entre los procesos que participan de forma explícita para evitar innecesaria sobre-sincronización.

Barrera (partes [, la acción [, timeout]])

Crear una compartida threading.Barrier objeto y devolver un proxy para ello.

counters = [0, 0]

barrier = threading.Barrier(2)

def count(thread_num, steps):

for i in range(steps):

other = counters[1 – thread_num]

barrier.wait() # wait for reads to complete

counters[thread_num] = other + 1

barrier.wait() # wait for writes to complete

def threaded_count(steps):

other = threading.Thread(target=count, args=(1, steps))

other.start()

count(0, steps)

print(‘counters:’, counters)

threaded_count(10)

En este ejemplo, la lectura y la escritura a los datos compartidos tienen lugar en diferentes fases, separados por barreras. Las escrituras se producen en la misma fase, pero son disjuntos; esta disjunción es necesario para evitar escrituras concurrentes a los mismos datos en la misma fase.Puesto que este código está sincronizada correctamente, ambos contadores siempre serán 10 en el extremo.

La partícula multiproceso simulador utiliza una barrera de una manera similar para sincronizar el acceso a los datos compartidos. En la simulación, cada hilo posee un número de partículas, todos los cuales interactúan entre sí a lo largo de muchos timesteps discretos. Una partícula tiene una posición, velocidad y aceleración, y una nueva aceleración se calcula en cada paso de tiempo basado en las posiciones de las otras partículas. La velocidad de la partícula debe ser actualizado en consecuencia, y su posición de acuerdo con su velocidad.

Al igual que con el simple ejemplo de arriba, hay una fase de lectura, en la que todas las posiciones de las partículas “son leídas por todos los temas. Cada hilo actualiza la aceleración de sus propias partículas ‘en esta fase, pero ya que estas son las escrituras disjuntos, no tiene por qué ser sincronizado. En la fase de escritura, cada hilo actualiza velocidades y posiciones de sus propias partículas. Una vez más, estos son escrituras disjuntos, y están protegidos de la fase de lectura por barreras.

Referencias:

http://composingprograms.com/pages/47-parallel-computing.html

https://docs.python.org/3/library/multiprocessing.html

Anuncios

Semáforos en Python

fondo

Ésta es una de las más antiguas primitivas de sincronización de la historia de la ciencia informática. Fue inventada por el informático teórico holandés Edsger W. Dijkstra (él utilizaba P() y V() en lugar de acquire() y release()).

Un semáforo actúa como un contador con un valor inicial.

  • Cada vez que un hilo llama a Semaphore.acquire(), el contador se decrementa en 1 y se deja pasar al hilo. En el momento que el contador se hace cero, NO se deja pasar al siguiente hilo que llame a acquire(), sino que lo deja bloqueado.
  • Cada vez que se llama a Semaphore.release(), el contador se incrementa en 1. Si se hace igual a cero, libera al siguiente hilo en la cola de espera.

Un semáforo gestiona un contador interno que se decrementa en cada llamada a acquire() y se incrementa en cada llamada a release(). El contador nunca puede bajar de cero. Si una llamada a acquire() se encuentra el contador a cero, bloquea la ejecución del hilo en curso y queda a la espera de que otro hilo llame arelease().

Semaphore ([value])

El argumento opcional proporciona el valor inicial del contador interno. El valor predeterminado es 1.

acquire ([blocking])

Adquirir un semáforo.

Si se invoca sin argumentos: si el contador interno es superior a cero a la entrada, lo decrementa en una unidad y retorna de inmediato. Si es cero a la entrada, bloquear la ejecución del hilo, esperando a que otro llame a release() para hacerlo mayor de cero. Se gestionan de manera adecuada los interbloqueos, por lo que si hay varias llamadas a acquire() bloqueadas a la espera, release() despertará exactamente a una de ellas. La implementación puede seleccionar una al azar, por lo que no se debe confiar en un orden de respuesta observado. No hay valor de retorno en este caso.

Si se invoca con el argumento blocking a verdadero, hacer lo mismo que si se llama sin argumentos y devolver verdadero.

Si se invoca con blocking a falso, no bloquear. Si una llamada sin argumentos bloquearía, devolver falso de inmediato. En caso contrario, hacer lo mismo que si se llama sin argumentos y devolver verdadero.

release ()

Liberar un semáforo, incrementando su contador interno en una unidad. Si era cero a la entrada y otro hilo está esperando a que sea mayor que cero, despertar a dicho hilo.

Para ver su funcionamiento basta observar el siguiente ejemplo sencillo. En anteriores entradas del blog podemos observar todo lo relativo al módulo Threading. Por otro lado, se debe crear el semáforo indicando el valor inicial del contador (número máximo de hilos que pueden estar activos simultáneamente):

import threading

from time import sleep

n_sem = 1

semaforo = threading.Semaphore(n_sem)

class Hilo(threading.Thread):

def __init__(self, id):

threading.Thread.__init__(self)

self.id = id

def run(self):

semaforo.acquire()

print “Hilo %s entra.”%(self.id)

sleep(3)

semaforo.release()

hilos = [Hilo(1), Hilo(2), Hilo(3)]

for h in hilos:

h.start()

Referencias:

http://pyspanishdoc.sourceforge.net/lib/semaphore-objects.html

https://pythonr2.wordpress.com/2008/09/01/sincronizacion-de-hilos-en-python/

http://mundogeek.net/archivos/2008/04/18/threads-en-python/

Práctica 5 Lectura Exclusiva/Escritura Exclusiva

#Practica 5 Suma EREW
#Noe Jimenez Peñaloza

import threading
import math

#Definicion de Funciones
def hilo(i,j):
if ((2*j)%(2**i)==0):
a[int(2*j)]=a[int(2*j)]+a[int((2*j)-2**(i-1))]
print a

#Programa principal
a=[0,7,1,3,1,2,1,8,4]
n=len(a)
lg=int(math.log(n,2))
print a
i=1
while(i<=lg):
j=1
while(j<=(n/2)):
t=threading.Thread(target=hilo, args=(i,j, ))
t.start()
j=j+1
i=i+1

Programación de Hilos en Python

En python, los threads  se realizan a través del módulo threading (basado en el módulo mas prehistórico thread), y consiste en ir expandiendo la clase para añadir threads.

import threading

class hilo(threading.Thread):

           #el constructor no hace falta especificarlo ya que la clase lo hace por nosotros.

           def __init__(self): 

                   threading.Thread.__init__(self)

           def run(self):

                   while True:

                          print “se esta ejecutando el hilo1”

           #el método run es donde se debe introducir el código que se ejecuta en segundo plano.

 

class hilo2(threading.Thread):

             def run(self):

                    while True:

                           print “se esta ejecutando el hilo2”

Una vez que hemos creado los hilos como en este ejemplo, para ejecutarlos se haría de la siguiente forma:

mi_hilo1=hilo()

mi_hilo2=hilo2()

mi_hilo1.start()

mi_hilo2.start()

De esta forma conseguiríamos ejecutar dos “while True” al mismo tiempo, otra cosa que hay que explicar, es que cuando creamos un hilo, aparte de existir el método “start” para iniciar el hilo también existe el método “join”, con este método se consigue bloquear la ejecución normal del programa hasta que termine el hilo, ejemplo:

class hilo(threading.Thread):

         def run(self):

                   mensaje=raw_input(“escribe algo “)

mi_hilo=hilo()

mi_hilo.start()

mi_hilo.join()

print “se a cerrado el hilo”
raw_input()

En este caso hasta que no se escriba algo para terminar el hilo, no continuaría el programa.

También podemos crear un hilo a través de una función ya creada:

def suma(a, b):

          while True:

                a+=1

                b+=1

                print a+b

hilo=threading.Thread(target=suma, args=(5, 8))

hilo.start()

while True:

        print “este es el hilo principal del programa”

En este caso creamos a través de la función suma un hilo, lo único que creo que debería explicar, es que se usa la palabra reservada target para indicar la función que se va a ejecutar en el thread, y la palabra reservada args  que sirve para pasarle los argumentos a la función dentro de una tupla.

Programación Google App Engine con Python

También conocido comúnmente como GAE o App Engine nos abre la infraestructura de producción de Google  de forma gratuita como plataforma de desarrollo y hospedaje de aplicaciones web.

google-app-engine

El servicio fue lanzado el 7 de abril del 2008 como un servicio de cloud pero a diferencia de otros servicios en la nube como Amazon Web Services o Azure Services Platform de Microsoft, el servicio ofrecido por Google es un servicio de Plataforma como Servicio y no de Infraestructura como Servicio.

El uso de la infraestructura de servicio de Google App Engine es completamente gratuita hasta un Gigabyte de almacenamiento y cinco millones de visitas mensuales. Si superamos esos límites entonces tendremos que pagar por más recursos a Google a unos precios bastante asequibles. Además podemos usar un dominio propio para la URL de nuestra aplicación o bien podemos usar un subdominio de appspot.com ofrecido de manera gratuita por Google al estilo de Heroku.

Google App Engine soporta diferentes lenguajes de programación como: Groovy, JRuby, Scala, PHP, Clojure, Perl, entre otros. Nosotros nos enfocaremos en el desarrollo con el lenguaje Python.

Para el desarrollo de aplicaciones Google App Engine con Python.

  • Descargar el software correspondiente para la ejecución de Python de acuerdo con tu versión de sistema operativo con el siguiente link: https://www.python.org/ .Tomar en cuenta que en Linux y Mac ya está instalado Python.
  • Para ejecutar el servidor del entorno de desarrollo tan solo debemos ejecutar el scriptdev_appserver.py y como parámetro el path al directorio que contiene la aplicación. Por ejemplo en una consola de un sistema tipo UNIX:

              genbeta@dev ~ $ python dev_appserver.py mi_app

Con Windows, Tecla de Windows + R , en el recuadro escribir cmd y presionamos ‘Enter’; con la terminal verificamos que ya tenemos instalado Python.

C:\Users\Adm> python

Verificar Sistema Operativo y versión.

  • Ejecutar Google App Engine Launcher -> Create New Application (Ctrl + N).Asignamos nombre a la aplicación (helloworld) y destino donde se guardara la misma aplicación (C:\User\Adm\Documentos\helloworld). En el puerto se queda igual.

Para abrir la pagina destino en el buscador escribimos localhost:0080

  • En la ruta donde guardamos los archivos, buscamos y abrimos el archivo app.yaml.
  • En versión lo cambiamos por dev , Runtime : python27, Api_version: 1
  • Las demás lineas se dejan exactamente igual.
  • En la misma ruta de los archivos localizamos el archivo main.py y la abrimos. Las demás líneas se dejan exactamente igual.
  • En la misma ruta de los archivos localizamos el archivo main.py y la abrimos.Aqui mismo podemos editar el codigo( Opciones->Edit with IDLE) para realizar las tareas requeridas.

Referencias:

https://code.google.com/p/google-app-engine-samples/

https://appengine.google.com/start

https://platzi.com/blog/google-app-engine/

Programación GUI con Python

Día con día nos vemos inmersos en la programación y desde la invención de la computadora se ha vuelto una herramienta primordial para el desarrollo de sistemas orientados a dar solución a los problemas de la vida cotidiana.

Python es un lenguaje de muy alto nivel que nos ofrece muchas alternativas para la programación GUI, en el siguiente enlace nos muestra a detalle las herramientas disponibles para llevar a cabo esta tarea.

Python-logo-notext.svg

Programación GUI con Python