If you are just getting started in Python and would like to learn more, take Datacamp’s Introduction to Data Science in Python course.
Introdução
Threading permite que você tenha diferentes partes do seu processo de executar simultaneamente (Fonte: RealPython). Estas diferentes partes são geralmente individuais e têm uma unidade separada de execução pertencente ao mesmo processo., O processo não é nada mais que um programa em execução que tem unidades individuais que podem ser executadas simultaneamente. Por exemplo, um navegador web pode ser um processo, uma aplicação executando várias câmeras simultaneamente pode ser um processo; um jogo de vídeo é outro exemplo de um processo.
dentro de um processo vem o conceito de thread múltipla ou comumente conhecido como multi-threading, onde vários threads trabalham juntos para alcançar um objetivo comum. O benefício mais crucial de usar threads é que ele permite que você execute o programa em paralelo.,
vamos entender o conceito de threading com a ajuda de um exemplo. Imagine que você tem uma aplicação que conta o número de carros que entram e saem do estacionamento do shopping. Seu aparelho tem várias câmeras que monitoram a entrada e saída conectando-se a um dispositivo central. Cada câmera terá um algoritmo para monitorar o fluxo de carros, que pertencerá ao mesmo processo ou programa. No entanto, cada câmera, juntamente com o algoritmo que está sendo executado, pode ser parte de um fio separado., Não só isso, mas mesmo os quadros que estão sendo lidos da câmera e o algoritmo que prevê nos quadros também podem ser dois threads separados.
outro exemplo pode ser um jogo de vídeo no qual o processo tem que executar as tarefas em paralelo, como os gráficos, interação do Usuário e rede (enquanto joga jogos multiplayer), porque ele tem que ser responsivo em todos os momentos. E para conseguir isso, ele tem que fazer uso do conceito de multi-thread, onde cada thread seria responsável por executar cada tarefa independente e individual.,
uma thread tem seu fluxo de execução, o que significa que o processo terá várias coisas acontecendo ao mesmo tempo.
é importante notar que cada processo tem pelo menos um fio, e que é chamado de id
. Se o seu programa não tem nenhuma thread definida, então ele terá pelo menos a thread principal, ou seja, o processo em si.
Se você olhar para o diagrama acima, há um processo que consiste no fio principal consistindo de variáveis globais e três threads diferentes t1, t2, e t3. Cada thread tem suas variáveis locais e fluxo de execução de código., Os threads geralmente compartilham os recursos do processo, como os recursos disponíveis para a principal thread também serão compartilhados entre os três threads t1, t2 e t3. Todas as threads terão acesso às variáveis globais enquanto têm suas próprias variáveis locais.,
Existem diferentes tipos de linhas:
- thread de Kernel
- thread do Usuário
- Combinação de kernel e de usuário thread
Agora vamos olhar para algumas das vantagens de ter enfiar no seu programa:
-
Multi-threading permite que o programa para acelerar a execução, desde que tenha várias CPUs.
-
também lhe permite executar outras tarefas enquanto as operações de E / S estão a ser realizadas com a ajuda de vários tópicos ou mesmo o tópico principal, juntamente com um único tópico., Por exemplo, a velocidade a que os quadros da câmera são lidos e inferidos pelo algoritmo será manuseada por diferentes threads. Assim, o algoritmo não terá que esperar que a moldura seja intransferida, e a parte de leitura da moldura não terá que esperar que a execução do algoritmo seja concluída para ser capaz de ler a próxima moldura.
- Threads dentro do mesmo processo podem compartilhar a memória e os recursos do tópico principal.,
desafios de roscagem:
-
lembre-se que o Python funciona com base na implementação de CPython, o que limita apenas um tópico a ser executado de cada vez, portanto; a roscagem pode não acelerar todas as tarefas. E a razão essencial por trás disso é Global Interpreter Lock (GIL).
Se você gostaria de aprender sobre GIL, então sinta-se à vontade para verificar este tutorial.
-
Se estiver à procura de acelerar a tarefa intensiva de CPU, então a roscagem pode não ser a melhor solução para si. Nesses casos, o processamento múltiplo é considerado útil.,
-
para executar um programa composto por vários tópicos, ele precisa mudar rapidamente através de tópicos; portanto, o agendamento precisa ser cuidado em programas onde você tem um monte de tópicos.
-
partilha de recursos também pode ser um problema, uma vez que todos os threads partilham os mesmos recursos e memória das variáveis globais. Assim, as operações realizadas em um thread podem causar um erro de memória para outro thread, ou o outro thread pode não obter a memória para executar sua tarefa.,
Threading em Python
-
Em Python, o módulo threading é um built-in módulo que é conhecido como
threading
e pode ser diretamente importado. -
Uma vez que quase tudo em Python é representado como um objeto, threading também é um objeto em Python. Um fio é capaz de guardar dados, armazenados em estruturas de dados como dicionários, listas, conjuntos, etc.
- Pode ser passado como um parâmetro para uma função.
a thread can also be executed as a process.,
um tópico em Python pode ter vários estados como:
- espera,
- bloqueado.
vamos agora aprender como você pode implementar threading em Python.
Thread module in Python3
Note that Python3 is backward compatible with thethread
module, which exists in Python2.7. In Python3, it can be imported as _thread
module. Então, vamos tomar um exemplo e entender o módulo _thread
.,
import _thread #thread module importedimport time #time module
vamos definir uma função chamada thread_delay
, que tomará dois parâmetros como uma entrada, ou seja, o nome do tópico e o atraso. Dentro desta função, você deverá:
- Define um contador com zero,
- , em Seguida, você volta com um loop while que será executado por três vezes,
- Dentro do while loop, você vai colocar
time.sleep()
adicionar atraso, esse atraso vai ser útil para compreender a execução da thread., Este atraso será em segundos; - então você irá aumentar o seu contador em 1,
- para ver se a sua execução do tópico está a correr bem, você irá imprimir o nome do tópico e a hora em que o tópico é executado.
def thread_delay(thread_name, delay): count = 0 while count < 3: time.sleep(delay) count += 1 print(thread_name, '-------->', time.time())
Agora, para adicionar o segmento de funcionalidade na função acima ou para executar a função acima na thread, você deve usar start_new_thread
método, que está dentro de _thread module
.
Let’s see the docstring of the start_new_thread
method.,
?_thread.start_new_thread
Vamos passar na função thread_delay
sem parênteses e dois argumentos, por exemplo, nome do thread e o atraso (para visualizar o thread de execução, pois é muito rápido).
_thread.start_new_thread(thread_delay, ('t1', 1))_thread.start_new_thread(thread_delay, ('t2', 3))
da saída acima, você pode ver que a linha t1
começa a executar primeiro., Enquanto isso, a linha t2
aguarda uma vez que há um atraso de 3 segundos, e assim que o atraso é concluído, a linha t2
é executado, e ainda, o atraso para o thread t1
é apenas 1 segundo.
Vamos agora alterar o atraso de t2
5 segundos, o que teria início t2
depois t1
teria terminado a execução desde t1
vai levar apenas 3 segundos para concluir a sua execução.,
_thread.start_new_thread(thread_delay, ('t1', 1))_thread.start_new_thread(thread_delay, ('t2', 5))
Execução de threading usando o módulo Threading
Vamos usar o mesmo exemplo que você usou acima, mas desta vez você vai usar o threading
módulo em vez de _thread
módulo.
import threadingimport time
def thread_delay(thread_name, delay): count = 0 while count < 3: time.sleep(delay) count += 1 print(thread_name, '-------->', time.time())
Dentro de threading
módulo é uma Thread
class, que é um espírito semelhante ao start_new_thread
função de _thread
módulo.,
Let’s look at the docstring of Thread
class, which takes in several parameters like group, target (like a function), args, etc.
?threading.Thread
Na Thread do construtor de classe, você vai passar a função de destino thread_delay
e os argumentos dessa função.,
t1 = threading.Thread(target=thread_delay, args=('t1', 1))t2 = threading.Thread(target=thread_delay, args=('t2', 3))
no módulo de threading, para executar ou executar o thread, você faz uso do método start()
, que é simplesmente responsável por executar o thread.
?t1.start
t1.start()t2.start()
Você também vai usar o join
método, o que significa que esperar até que todos o thread de execução é concluída., Assim, qualquer código que tenha escrito após o método join
só será executado quando estes tópicos terminarem.
?t1.join
t1.start()t2.start()t1.join()t2.join()print("Thread execution is complete!")
Agora, vamos calcular o volume do cubo e o quadrado usando o rosqueamento conceito, o que é muito para a frente.
def volume_cube(a): print ("Volume of Cube:", a*a*a)
def volume_square(a): print ("Volume of Square:", a*a)
t1 = threading.Thread(target=volume_cube, args=(2))t2 = threading.Thread(target=volume_square, args=(3))
t1.start()t2.start()t1.join()t2.join()print("Thread execution is complete!")
Espere, o que? Assim que você executou o método inicial, ele resultou em um erro., Isso é porque o args
parâmetro espera uma tupla, e desde que o volume_cube
e volume_square
espera apenas um parâmetro, por isso, você precisa colocar uma vírgula no args
parâmetro depois de especificar o primeiro argumento das funções.
t1 = threading.Thread(target=volume_cube, args=(2,))t2 = threading.Thread(target=volume_square, args=(3,))
t1.start()t2.start()t1.join()t2.join()print("Thread execution is complete!")
Volume of Cube: 8Volume of Square: 9Thread execution is complete!
let’s now learn to use threading as a subclass.,
Threading como uma sub-classe
nesta seção, você aprenderá como criar sub-classe da classe thread, que está disponível dentro de threading do módulo e, em seguida, criar thread instâncias t1
e t2
fora da classe.
Você usaria a mesma função thread_delay
função aqui também.
Agora vamos entender o código acima o passo a passo:
-
Você tiver definido uma classe
DataCampThread
, e no argumento de classe, que passou nothreading.Thread
classe., A razão pela qual você faz isso é que você quer criar uma sub-classe a partir do módulo de threading. Fazendo isso, você pode usar todos os métodos que estão disponíveis na classethreading.Thread
semelhante ao conceito de herança. -
em seguida, você definiu o método init da classe DataCampThread e passou na função juntamente com o atraso. O init é um construtor semelhante aos parâmetros que você passou para a classe
threading.Thread
, aqui você estaria passando para a classe ., -
Depois inicializa o método init da roscagem principal.Classe de Thread e, em seguida, igualar o nome e atraso.
-
A seguir, você define o método
run
, lembre-se aqui você definiu o métodostart
, que basicamente por baixo da capa chama o métodorun
. Uma vez que você herdou a classe principal, você está autorizado a fazer alterações no métodorun
., Assim, quando você chamar o métodostart
, quaisquer modificações que você fará no métodorun
serão refletidas agora.
conclusão
parabéns por terminar o tutorial.
Este tutorial foi uma introdução básica à threading em python. No entanto, threading é um tópico muito vasto e vital, e alguns conceitos podem ter sido deixados por explorar. Sinta-se livre para olhar para mais métodos de rosca como contagem ativa, thread atual, etc.
Se você gostaria de aprender mais, então também Confira o paralelismo baseado em Thread do Python.,
Se você está apenas começando em Python e gostaria de saber mais, tome a introdução de DataCamp para ciência de dados no curso Python.