Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial programming >> python

Programación Multihilo en Python: Técnicas Eficientes de Concurrencia

Ejecutar varios hilos es similar a ejecutar varios programas concurrentemente, pero con beneficios:

Un hilo tiene inicio, secuencia de ejecución y conclusión. Mantiene un puntero de instrucción que rastrea dónde está ejecutándose actualmente.

Iniciar un Nuevo Hilo (Módulo thread)

Para crear un hilo, usa el método del módulo thread (Python 2) o _thread (Python 3):

thread.start_new_thread(function, args[, kwargs])

Retorna inmediatamente y el hilo hijo comienza ejecutando function con args. Cuando la función retorna, el hilo termina.

args es una tupla de argumentos (usa tupla vacía para sin argumentos). kwargs es diccionario opcional de argumentos por palabra clave.

Ejemplo

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

def print_time(threadName, delay):
    count = 0
    while count < 5:
        time.sleep(delay)
        count += 1
        print("%s: %s" % (threadName, time.ctime(time.time())))

try:
    thread.start_new_thread(print_time, ("Thread-1", 2))
    thread.start_new_thread(print_time, ("Thread-2", 4))
except:
    print("Error: unable to start thread")

while 1:
    pass

El módulo thread es efectivo para bajo nivel pero limitado comparado con threading.

El Módulo threading

El módulo threading (Python 2.4+) proporciona soporte potente de alto nivel para hilos.

Expone métodos de thread y añade:

Clase Thread con métodos:

Crear Hilo con Threading

Pasos:

Crea instancia y llama start() (que invoca run()).

Ejemplo

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

exitFlag = 0

class myThread(threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter

    def run(self):
        print("Starting " + self.name)
        print_time(self.name, 5, self.counter)
        print("Exiting " + self.name)

def print_time(threadName, counter, delay):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

# Crear hilos
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# Iniciar hilos
thread1.start()
thread2.start()

print("Exiting Main Thread")

Sincronización de Hilos

El módulo threading incluye mecanismo de bloqueo (lock) simple para sincronizar hilos.

Ejemplo

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

class myThread(threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter

    def run(self):
        print("Starting " + self.name)
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

threadLock = threading.Lock()
threads = []

thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

thread1.start()
thread2.start()

threads.append(thread1)
threads.append(thread2)

for t in threads:
    t.join()

print("Exiting Main Thread")

Cola de Prioridad Multihilo (Queue)

El módulo Queue (Python 2) / queue (Python 3) permite crear colas con capacidad específica.

Métodos de control:

Ejemplo Completo

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

exitFlag = 0

class myThread(threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q

    def run(self):
        print("Starting " + self.name)
        process_data(self.name, self.q)
        print("Exiting " + self.name)

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print("%s processing %s" % (threadName, data))
        else:
            queueLock.release()
            time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]

queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []
threadID = 1

# Crear hilos
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# Llenar cola
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# Esperar a que cola se vacíe
while not workQueue.empty():
    pass

# Notificar salida
exitFlag = 1

# Esperar hilos
for t in threads:
    t.join()

print("Exiting Main Thread")

Resultado: Los hilos procesan elementos de la cola concurrentemente con sincronización.

Nota: En Python 3, usa import queue y queue.Queue(). El módulo thread se renombró a _thread.

python

  1. Dominando el Ciclo de Rosca Fanuc G76: Guía Completa para Maquinistas CNC
  2. Formado de roscas vs. laminado de roscas: diferencias clave
  3. Dominando tipos de datos en Python: Guía práctica
  4. Dominando operadores en Python: Guía completa
  5. Dominando el bucle while en Python: Sintaxis, ejemplos y mejores prácticas
  6. Dominando la sentencia pass en Python: Guía práctica
  7. Dominando argumentos de funciones en Python: Posicionales, por palabra clave y por defecto
  8. Dominando Diccionarios en Python: Creación, Manipulación y Técnicas Avanzadas
  9. Dominando la Programación Orientada a Objetos en Python: Clases, Herencia, Encapsulación y Polimorfismo
  10. Programación de Redes en Python: Sockets y Protocolos Avanzados
  11. Programación de Extensiones en Python con C: Crea Módulos Nativos Rápidos