Manufaturação industrial
Internet das coisas industrial | Materiais industriais | Manutenção e reparo de equipamentos | Programação industrial |
home  MfgRobots >> Manufaturação industrial >  >> Industrial programming >> python

Programação Multithread em Python: Concorrência Eficiente

Executar várias threads é semelhante a rodar vários programas simultaneamente, mas com vantagens:

Uma thread tem início, sequência de execução e fim, com um ponteiro de instrução. Pode ser preemptada (interrompida) ou colocada em espera (sleep/yield).

Iniciando Nova Thread (módulo thread – baixo nível)

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

Retorna imediatamente; a thread filha executa funcao(*args, **kwargs) e termina quando a função retorna.

Exemplo

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

def imprimir_tempo(nome, atraso):
    cont = 0
    while cont < 5:
        time.sleep(atraso)
        cont += 1
        print(f"{nome}: {time.ctime(time.time())}")

try:
    thread.start_new_thread(imprimir_tempo, ("Thread-1", 2))
    thread.start_new_thread(imprimir_tempo, ("Thread-2", 4))
except:
    print("Erro ao iniciar thread")

while True:
    pass  # mantém programa vivo

Limitação: O módulo thread é limitado; prefira o módulo threading (alto nível).

Módulo threading

Fornece suporte avançado. Métodos extras:

Classe Thread

Criando Thread com threading

  1. Subclasse threading.Thread.
  2. Sobrescreva __init__ para argumentos extras.
  3. Sobrescreva run com a lógica.
  4. Instancie e chame start().

Exemplo

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

class MinhaThread(threading.Thread):
    def __init__(self, thread_id, nome, contador):
        super().__init__()
        self.thread_id = thread_id
        self.nome = nome
        self.contador = contador

    def run(self):
        print(f"Iniciando {self.nome}")
        imprimir_tempo(self.nome, self.contador, 5)
        print(f"Saindo {self.nome}")

def imprimir_tempo(nome, contador, atraso):
    while contador:
        time.sleep(atraso)
        print(f"{nome}: {time.ctime(time.time())}")
        contador -= 1

t1 = MinhaThread(1, "Thread-1", 1)
t2 = MinhaThread(2, "Thread-2", 2)
t1.start()
t2.start()
print("Saindo da thread principal")

Sincronização com Locks

Use threading.Lock() para evitar condições de corrida.

Exemplo com Lock

lock = threading.Lock()

class MinhaThread(threading.Thread):
    def run(self):
        print(f"Iniciando {self.name}")
        lock.acquire()
        imprimir_tempo(self.name, self.counter, 3)
        lock.release()

threads = []
for i in range(2):
    t = MinhaThread(i+1, f"Thread-{i+1}", i+1)
    t.start()
    threads.append(t)

for t in threads:
    t.join()
print("Saindo da thread principal")

Fila de Prioridade Multithread (queue.Queue)

Fila thread-safe para comunicação produtor-consumidor.

Exemplo Produtor-Consumidor

import queue, threading, time

fila = queue.Queue(10)
lock_fila = threading.Lock()
exit_flag = 0

class Worker(threading.Thread):
    def __init__(self, nome, fila):
        super().__init__()
        self.nome = nome
        self.fila = fila

    def run(self):
        print(f"Iniciando {self.nome}")
        while not exit_flag:
            lock_fila.acquire()
            if not self.fila.empty():
                dado = self.fila.get()
                lock_fila.release()
                print(f"{self.nome} processando {dado}")
            else:
                lock_fila.release()
                time.sleep(1)
        print(f"Saindo {self.nome}")

# Cria threads
threads = [Worker(f"Thread-{i}", fila) for i in range(3)]
for t in threads: t.start()

# Preenche fila
lock_fila.acquire()
for palavra in ["Um", "Dois", "Três", "Quatro", "Cinco"]:
    fila.put(palavra)
lock_fila.release()

# Aguarda fila esvaziar
while not fila.empty():
    pass
exit_flag = 1

for t in threads: t.join()
print("Saindo da thread principal")

Nota: Em Python 3, use queue (minúsculo) e métodos is_alive(), active_count(), etc.

python

  1. Formação de Rosca vs Laminação de Rosca: Entendendo as Diferenças Principais
  2. Dominando Tipos de Dados em Python: Guia Prático
  3. Dominando Operadores em Python: Guia Completo
  4. Dominando a Declaração Pass em Python: Guia Prático
  5. Dominando Argumentos de Funções em Python: Parâmetros Posicionais, Nomeados e Padrão
  6. Dominando Dicionários em Python: Criação, Manipulação e Técnicas Avançadas
  7. Dominando Programação Orientada a Objetos em Python: Classes, Herança, Encapsulamento e Polimorfismo
  8. Programação de Rede em Python: Sockets e Protocolos Avançados
  9. Programação de Extensões Python com C: Criando Módulos Nativos Rápidos
  10. Dominando o Ciclo de Rosqueamento Fanuc G76: Guia Completo para Operadores CNC