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