Programacion Multihilo en Python mediante Ejemplos

  • por javier
  • 22 de Marzo de 2023
None

Mini - Ladrillo

En determinadas ocasiones, resulta necesario ejecutar varias tareas al mismo tiempo para ganar en velocidad de proceso. 
Estas tareas pueden ser similares o bien diferentes y a veces utilizan el mismo recurso simultaneamente o bien necesitan comunicarse entre ellos para coordinarse; esto puede dar problemas, pero la programación multihilo nos permite solucionar estas situaciones mediante varios recursos, cada uno adecuado o necesario en un caso u otro. 

Estos recursos son :
- Semáforos. Permiten acceder a un recurso y liberarlo cuando queramos.
- Bloqueos. Bloquean el recurso hasta que es liberado para su reutilización por parte de otro hilo.
- Condiciones. Este caso es similar a los anteriores, pero permite notificar cuando el recurso es liberado.

En los 3 casos, podemos definir el número de accesos simultáneos. Podría ser 1, 2 o los que queramos, siempre y cuando el recurso a utilizar aguante dicha carga sin fallar.

El Código
Comenzamos con algo sencillo: un solo hilo que se ejecuta de forma simultánea al hilo principal.

#!/usr/bin/python

import threading
import time

def hilo(i):
    """:param i: numero de hilo a efectos ilustrativos :return: nada """ 
    print "[+] En hilo %d\n" % i 
    time.sleep(3) 
    print "[-] hilo %d finalizado" 
# Creacion y Ejecucion de 1 hilo paralelo a hilo 2 
simplethread=threading.Thread(target=hilo, args=[1]) 
simplethread.start() 
# Esto se ejecuta como proceso principal 
hilo(2) # Esperamos a que acabe el hilo paralelo 1 
simplethread.join()

En este caso, no hay interacción ni compartimos recursos: 1 hilo, 1 proceso principal.
En el siguiente caso, ya, vamos a ejecutar varios hilos simultáneamente. No compartimos recursos ni hay sincronía alguna entre procesos.

#!/usr/bin/python
import threading
import time

NTHREADS=20
def hilo(i):
    """ :param i: numero de hilo a efectos ilustrativos :return: nada """
    print "[+] En hilo %d" % i 
    time.sleep(3) 
    print "[-] hilo %d finalizado" % i 
simplethread=[] 
for i in range(NTHREADS): 
    # arranque y comienzo de hilo num i+1 
    simplethread.append(threading.Thread(target=hilo, args=[i+1])) 
    simplethread[-1].start() 
for i in range(NTHREADS): 
    # esperamos que acabe el hilo num i 
    simplethread[i].join() 
print "[*] all threads finished"

En este ejemplo, usamos semáforos, que son la forma mas primitiva de compartir recursos. El ejemplo consiste en la salida por un tunel por parte de varias personas. Solo puede entrar una a la vez.

#!/usr/bin/python
import threading
from threading import Semaphore 
import time
NTHREADS=20
WIDTH=1

sem=Semaphore(WIDTH)
def hilo(i):
    """:param i: numero de hilo a efectos ilustrativos :return: nada """
    print "[+] En hilo %d" % i
    time.sleep(3)
    sem.acquire()
    print "[+] En tunel hilo %d" % i   
    time.sleep(1)
    sem.release()
    print "[-] hilo %d, estoy fuera" % i

simplethread=[]
for i in range(NTHREADS):
    # arranque y comienzo de hilo num i+1
    simplethread.append(threading.Thread(target=hilo, args=[i+1]))
    simplethread[-1].start()

for i in range(NTHREADS):
    # esperamos que acabe el hilo num i
    simplethread[i].join()
print "[*] all"

El siguiente ejemplo, ilustra los bloqueos de recursos. En este caso RLock.
Simula varias personas bebiendo de un solo vaso. Todos beben a la misma velocidad.

#!/usr/bin/python
import threading
from threading
import RLock
import time

THREADS=20 # Bloqueo de un recurso mientras se usa
sem=RLock()
def hilo(i):
   """ :param i: numero de hilo a efectos ilustrativos :return: nada """
   print "[+] En hilo %d" % i
   time.sleep(3)

   with sem:
       print "[+] Bebiendo hilo %d..." % i
       time.sleep(1)
       print "[-] hilo %d satisfecho" % i

simplethread=[]
for i in range(NTHREADS):
    # arranque y comienzo de hilo num i+1
    simplethread.append(threading.Thread(target=hilo, args=[i+1]))
    simplethread[-1].start()

for i in range(NTHREADS):
   """ # esperamos que acabe el hilo num i"""
   simplethread[i].join()

print "[*] all threads finished"

Para terminar, ilustraré las Conditions. Estas formas de bloqueo de recursos son las más sofisticadas que hay. En el ejemplo, seguimos bebiendo, esta vez, cada uno bebe a su ritmo y notifica cuando terminó de beber al resto.

#!/usr/bin/python
import threading
from threading import Condition
import time
from random import randint

NTHREADS=20
# Bloqueo de un recurso mientras se usa
sem=Condition()
def bebe(i):
    s=randint(1,10)
    print "[+] Bebiendo hilo %d.. esperate %d secs" % (i,s)
    time.sleep(s)
    sem.notify(1)
    print "[-] estaba de muerte, hilos --%d--" % i
    sem.release()

def hilo(i):
    """ :param i: numero de hilo a efectos ilustrativos :return: nada """
    print "[+] En hilo %d" % i
    time.sleep(1)
    while not sem.acquire():
       sem.wait(0.5)
    else:
       bebe(i)
       print "[-] hilo %d finalizado" % i

simplethread=[]
for i in range(NTHREADS):
    # arranque y comienzo de hilo num i+1
    simplethread.append(threading.Thread(target=hilo, args=[i+1]))
    simplethread[-1].start()
for i in range(NTHREADS):
    # esperamos que acabe el hilo num i
    simplethread[i].join()

print "[*] all threads finished"

Espero que os haya interesado el artículo y muchas gracias por la lectura.
Saludos y hasta la proxima.

Descarga el codigo  demos_multihilo.tar.gz

blog comments powered by Disqus

Detecta dispositivos USB no autorizados en Linux (Extensible Python Snippet)

  • por javier
  • 21 de Marzo de 2023

La proliferación de dispositivos USB maliciosos, para hacerse con el control de nuestra máquina están a la orden del día.

Los hay muy variados y de diferente funcionalidad, y permiten un amplio rango de posibilidades a la hora de hackear nuestra máquina.

Contra esto, hay varias soluciones, como USBGuard, que no funciona bien en distros estables por problema de dependencias.

También hay otras soluciones como USB Canary que permite twittear y enviar sms con Twilio para avisarnos de dichos ataques.

No obstante, me he permitido el lujo de crear un snippet algo más abierto y sencillo para que modifiqueis a vuestro antojo y en base a vuestras necesidades.

Se me ocurre integrarlo con OSSEC, por ejemplo, con una regla e incorporarlo vuestro sistema de alertas..

ALGORITMOS GENETICOS. PROBLEMA DE LAS 8 REINAS EN PYTHON

  • por javier
  • 22 de Marzo de 2023
None

La idea de Algoritmos Genéticos, se basa en la teoría de la evolución de las especies, de Charles Darwin (1859). La idea principal es que las variaciones o mutaciones, ocurren en la reproducción y serán conservadas en base a la idoneidad reproductiva.

Los Algoritmos Genéticos se basan en la búsqueda paralela de soluciones, hasta dar con una suficientemente válida o se aborta el programa si no se encuentra dicha solución y el tiempo transcurrido de cómputo no es aceptable.

Inicialmente se genera una población (soluciones posibles en un array), que van regenerándose en base a un cruce de 2 individuos (cadenas de genes o ADN) de dicha población, sucesivamente y aleatoriamente, se mutan genes del individuo en cuestión.

Posibles aplicaciones de Deep Learning

  • por javier
  • 22 de Marzo de 2023

Machine Learning y Deep Learning comenzaron su andadura en el siglo pasado y están de moda últimamente gracias a una mayor capacidad de cómputo en nuestras máquinas. En un futuro cercano, las aplicaciones de dicha tecnología aumentarán exponencialmente y acabarán siendo de uso cotidiano para cualquier programador. Podemos darle muchos usos al Machine Learning y a Deep Learning. En éste artículo me centraré en Deep Learning. En Deep Learning se utilizan Redes Neuronales ya sean Convolutional Neural Networks, Recurrent Neural Networks, Sequence Models… cada una de ellas tiene un uso específico pero nos centraremos más en los usos que se dan a dichas redes. Algunos usos son muy conocidos, pero solo el futuro podrá darnos la sorpresa de aplicaciones novedosas y poco conocidas hasta ahora.

Update cookies preferences