Python - Programação Multithread
A execução de vários threads é semelhante à execução de vários programas diferentes simultaneamente, mas com os seguintes benefícios -
-
Vários threads dentro de um processo compartilham o mesmo espaço de dados com o thread principal e, portanto, podem compartilhar informações ou se comunicar entre si mais facilmente do que se fossem processos separados.
-
Os threads às vezes são chamados de processos leves e não exigem muita sobrecarga de memória; são mais baratos que os processos.
Uma thread tem um início, uma sequência de execução e uma conclusão. Ele tem um ponteiro de instrução que mantém o controle de onde dentro de seu contexto ele está sendo executado no momento.
-
Pode ser antecipado (interrompido)
-
Ele pode ser temporariamente colocado em espera (também conhecido como suspensão) enquanto outros threads estão em execução - isso é chamado de rendimento.
Iniciando um novo tópico
Para gerar outro thread, você precisa chamar o seguinte método disponível em thread módulo -
thread.start_new_thread ( function, args[, kwargs] )
Essa chamada de método permite uma maneira rápida e eficiente de criar novos threads no Linux e no Windows.
A chamada do método retorna imediatamente e o thread filho inicia e chama a função com a lista passada de args . Quando a função retorna, a thread termina.
Aqui, args é uma tupla de argumentos; use uma tupla vazia para chamar a função sem passar nenhum argumento. kwargs é um dicionário opcional de argumentos de palavras-chave.
Exemplo
#!/usr/bin/python import thread import time # Define a function for the thread def print_time( threadName, delay): count = 0 while count < 5: time.sleep(delay) count += 1 print "%s: %s" % ( threadName, time.ctime(time.time()) ) # Create two threads as follows 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
Quando o código acima é executado, ele produz o seguinte resultado -
Thread-1: Thu Jan 22 15:42:17 2009 Thread-1: Thu Jan 22 15:42:19 2009 Thread-2: Thu Jan 22 15:42:19 2009 Thread-1: Thu Jan 22 15:42:21 2009 Thread-2: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:23 2009 Thread-1: Thu Jan 22 15:42:25 2009 Thread-2: Thu Jan 22 15:42:27 2009 Thread-2: Thu Jan 22 15:42:31 2009 Thread-2: Thu Jan 22 15:42:35 2009
Embora seja muito eficaz para encadeamento de baixo nível, mas o thread módulo é muito limitado em comparação com o módulo de rosqueamento mais recente.
O Enroscamento Módulo
O módulo de encadeamento mais recente incluído no Python 2.4 fornece suporte muito mais poderoso e de alto nível para encadeamentos do que o módulo de encadeamento discutido na seção anterior.
O encadeamento módulo expõe todos os métodos do thread módulo e fornece alguns métodos adicionais -
-
threading.activeCount() − Retorna o número de objetos de thread que estão ativos.
-
threading.currentThread() − Retorna o número de objetos de thread no controle de thread do chamador.
-
threading.enumerate() − Retorna uma lista de todos os objetos de thread que estão ativos no momento.
Além dos métodos, o módulo de threading possui o Thread classe que implementa o encadeamento. Os métodos fornecidos pelo Thread classe são as seguintes -
-
executar() − O método run() é o ponto de entrada para uma thread.
-
iniciar() − O método start() inicia uma thread chamando o método run.
-
join([tempo]) − O join() espera que as threads terminem.
-
estáAlive() − O método isAlive() verifica se uma thread ainda está em execução.
-
getNome() − O método getName() retorna o nome de uma thread.
-
setNome() − O método setName() define o nome de uma thread.
Criando thread usando Threading Módulo
Para implementar um novo encadeamento usando o módulo de encadeamento, você deve fazer o seguinte −
-
Defina uma nova subclasse do Thread classe.
-
Substituir o __init__(self [,args]) método para adicionar argumentos adicionais.
-
Em seguida, substitua o método run(self [,args]) para implementar o que o thread deve fazer quando iniciado.
Depois de criar o novo Tópico subclasse, você pode criar uma instância dela e então iniciar uma nova thread invocando a função start() , que por sua vez chama run() método.
Exemplo
#!/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 # Create new threads thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Start new Threads thread1.start() thread2.start() print "Exiting Main Thread"
Quando o código acima é executado, ele produz o seguinte resultado -
Starting Thread-1 Starting Thread-2 Exiting Main Thread Thread-1: Thu Mar 21 09:10:03 2013 Thread-1: Thu Mar 21 09:10:04 2013 Thread-2: Thu Mar 21 09:10:04 2013 Thread-1: Thu Mar 21 09:10:05 2013 Thread-1: Thu Mar 21 09:10:06 2013 Thread-2: Thu Mar 21 09:10:06 2013 Thread-1: Thu Mar 21 09:10:07 2013 Exiting Thread-1 Thread-2: Thu Mar 21 09:10:08 2013 Thread-2: Thu Mar 21 09:10:10 2013 Thread-2: Thu Mar 21 09:10:12 2013 Exiting Thread-2
Sincronizando Threads
O módulo de encadeamento fornecido com o Python inclui um mecanismo de bloqueio simples de implementar que permite sincronizar encadeamentos. Um novo bloqueio é criado chamando o método Lock() método, que retorna o novo bloqueio.
O adquirir(bloquear) O método do novo objeto de bloqueio é usado para forçar os threads a serem executados de forma síncrona. O bloqueio opcional O parâmetro permite controlar se o encadeamento aguarda para adquirir o bloqueio.
Se bloquear for definido como 0, o encadeamento retornará imediatamente com um valor 0 se o bloqueio não puder ser adquirido e com 1 se o bloqueio for adquirido. Se o bloqueio for definido como 1, o encadeamento será bloqueado e aguardará a liberação do bloqueio.
A liberação() O método do novo objeto de bloqueio é usado para liberar o bloqueio quando ele não é mais necessário.
Exemplo
#!/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 # Get lock to synchronize threads threadLock.acquire() print_time(self.name, self.counter, 3) # Free lock to release next thread 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 = [] # Create new threads thread1 = myThread(1, "Thread-1", 1) thread2 = myThread(2, "Thread-2", 2) # Start new Threads thread1.start() thread2.start() # Add threads to thread list threads.append(thread1) threads.append(thread2) # Wait for all threads to complete for t in threads: t.join() print "Exiting Main Thread"
Quando o código acima é executado, ele produz o seguinte resultado -
Starting Thread-1 Starting Thread-2 Thread-1: Thu Mar 21 09:11:28 2013 Thread-1: Thu Mar 21 09:11:29 2013 Thread-1: Thu Mar 21 09:11:30 2013 Thread-2: Thu Mar 21 09:11:32 2013 Thread-2: Thu Mar 21 09:11:34 2013 Thread-2: Thu Mar 21 09:11:36 2013 Exiting Main Thread
Fila de prioridade multiencadeada
A Fila O módulo permite que você crie um novo objeto de fila que pode conter um número específico de itens. Existem os seguintes métodos para controlar a Fila -
-
get() − O get() remove e retorna um item da fila.
-
colocar() − O put adiciona item a uma fila.
-
qsize() − O qsize() retorna o número de itens que estão atualmente na fila.
-
vazio() − O empty( ) retorna True se a fila estiver vazia; caso contrário, Falso.
-
completo() − o full() retorna True se a fila estiver cheia; caso contrário, Falso.
Exemplo
#!/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 # Create new threads for tName in threadList: thread = myThread(threadID, tName, workQueue) thread.start() threads.append(thread) threadID += 1 # Fill the queue queueLock.acquire() for word in nameList: workQueue.put(word) queueLock.release() # Wait for queue to empty while not workQueue.empty(): pass # Notify threads it's time to exit exitFlag = 1 # Wait for all threads to complete for t in threads: t.join() print "Exiting Main Thread"
Quando o código acima é executado, ele produz o seguinte resultado -
Starting Thread-1 Starting Thread-2 Starting Thread-3 Thread-1 processing One Thread-2 processing Two Thread-3 processing Three Thread-1 processing Four Thread-2 processing Five Exiting Thread-3 Exiting Thread-1 Exiting Thread-2 Exiting Main Thread
python
- Formação de Threads vs Thread Rolling:Qual é a diferença?
- Tipos de dados Python
- Operadores Python
- Instrução de passagem do Python
- Argumentos da função Python
- Dicionário Python
- Programação Orientada a Objetos Python
- Python - Programação de Rede
- Python - Programação de extensão com C
- Ciclo de rosca Fanuc G76 para leigos