Simultaneidade em Python - Introdução

Neste capítulo, entenderemos o conceito de simultaneidade em Python e aprenderemos sobre os diferentes threads e processos.

O que é simultaneidade?

Em palavras simples, a simultaneidade é a ocorrência de dois ou mais eventos ao mesmo tempo. A simultaneidade é um fenômeno natural porque muitos eventos ocorrem simultaneamente a qualquer momento.

Em termos de programação, a simultaneidade ocorre quando duas tarefas se sobrepõem na execução. Com a programação simultânea, o desempenho de nossos aplicativos e sistemas de software pode ser melhorado porque podemos lidar simultaneamente com as solicitações em vez de esperar que uma anterior seja concluída.

Análise histórica de simultaneidade

Os pontos a seguir nos darão uma breve revisão histórica da concorrência -

Do conceito de ferrovias

A simultaneidade está intimamente relacionada ao conceito de ferrovias. Com as ferrovias, havia a necessidade de lidar com vários trens no mesmo sistema ferroviário de forma que cada trem chegasse ao seu destino com segurança.

Computação simultânea na academia

O interesse na simultaneidade da ciência da computação começou com o artigo de pesquisa publicado por Edsger W. Dijkstra em 1965. Nesse artigo, ele identificou e resolveu o problema da exclusão mútua, a propriedade do controle de concorrência.

Primitivas de simultaneidade de alto nível

Recentemente, os programadores estão obtendo soluções concorrentes aprimoradas devido à introdução de primitivas de simultaneidade de alto nível.

Concorrência aprimorada com linguagens de programação

Linguagens de programação como Golang, Rust e Python do Google fizeram desenvolvimentos incríveis em áreas que nos ajudam a obter melhores soluções simultâneas.

O que é thread e multithreading?

Threadé a menor unidade de execução que pode ser executada em um sistema operacional. Não é em si um programa, mas é executado dentro de um programa. Em outras palavras, os threads não são independentes uns dos outros. Cada thread compartilha seção de código, seção de dados, etc. com outros threads. Eles também são conhecidos como processos leves.

Um thread consiste nos seguintes componentes -

  • Contador de programa que consiste no endereço da próxima instrução executável

  • Stack

  • Conjunto de registros

  • Um id único

Multithreading, por outro lado, é a capacidade de uma CPU de gerenciar o uso do sistema operacional executando vários threads simultaneamente. A ideia principal do multithreading é atingir o paralelismo dividindo um processo em vários threads. O conceito de multithreading pode ser entendido com a ajuda do exemplo a seguir.

Exemplo

Suponha que estejamos executando um processo específico em que abrimos o MS Word para digitar o conteúdo nele. Um thread será atribuído para abrir o MS Word e outro thread será necessário para digitar o conteúdo nele. E agora, se quisermos editar o existente, então outro thread será necessário para fazer a tarefa de edição e assim por diante.

O que é processo e multiprocessamento?

UMAprocessé definido como uma entidade, que representa a unidade básica de trabalho a ser implementada no sistema. Em termos simples, escrevemos nossos programas de computador em um arquivo de texto e quando executamos este programa, ele se torna um processo que realiza todas as tarefas mencionadas no programa. Durante o ciclo de vida do processo, ele passa por diferentes estágios - Iniciar, Pronto, Executando, Esperando e Encerrando.

O diagrama a seguir mostra os diferentes estágios de um processo -

Um processo pode ter apenas uma thread, chamada thread primária, ou múltiplas threads tendo seu próprio conjunto de registradores, contador de programa e pilha. O diagrama a seguir nos mostrará a diferença -

Multiprocessing,por outro lado, é o uso de duas ou mais unidades de CPUs em um único sistema de computador. Nosso objetivo principal é obter todo o potencial de nosso hardware. Para conseguir isso, precisamos utilizar o número total de núcleos de CPU disponíveis em nosso sistema de computador. O multiprocessamento é a melhor abordagem para isso.

Python é uma das linguagens de programação mais populares. A seguir estão alguns motivos que o tornam adequado para aplicativos simultâneos -

Açúcar sintático

Açúcar sintático é a sintaxe em uma linguagem de programação projetada para tornar as coisas mais fáceis de ler ou expressar. Isso torna a linguagem “mais doce” para uso humano: as coisas podem ser expressas de forma mais clara, mais concisa ou em um estilo alternativo baseado na preferência. Python vem com métodos Magic, que podem ser definidos para atuar em objetos. Esses métodos mágicos são usados ​​como açúcar sintático e vinculados a palavras-chave mais fáceis de entender.

Grande Comunidade

A linguagem Python testemunhou uma grande taxa de adoção entre cientistas de dados e matemáticos, trabalhando na área de IA, aprendizado de máquina, aprendizado profundo e análise quantitativa.

APIs úteis para programação simultânea

Python 2 e 3 têm grande número de APIs dedicadas para programação paralela / simultânea. Os mais populares deles sãothreading, concurrent.features, multiprocessing, asyncio, gevent and greenlets, etc.

Limitações do Python na implementação de aplicativos simultâneos

Python vem com uma limitação para aplicativos simultâneos. Esta limitação é chamadaGIL (Global Interpreter Lock)está presente no Python. GIL nunca nos permite utilizar múltiplos núcleos de CPU e, portanto, podemos dizer que não há threads verdadeiros no Python. Podemos entender o conceito de GIL da seguinte forma -

GIL (bloqueio global do intérprete)

É um dos tópicos mais polêmicos no mundo Python. Em CPython, GIL é o mutex - o bloqueio de exclusão mútua, que torna as coisas seguras no thread. Em outras palavras, podemos dizer que GIL evita que vários threads executem código Python em paralelo. O bloqueio pode ser mantido por apenas um encadeamento por vez e, se quisermos executar um encadeamento, ele deve primeiro adquirir o bloqueio. O diagrama mostrado abaixo irá ajudá-lo a entender o funcionamento do GIL.

No entanto, existem algumas bibliotecas e implementações em Python, como Numpy, Jpython e IronPytbhon. Essas bibliotecas funcionam sem qualquer interação com GIL.