Simultaneidade em Python - Threads

Em geral, como sabemos, esse fio é um fio torcido muito fino, geralmente feito de tecido de algodão ou seda e usado para costurar roupas e similares. O mesmo termo thread também é usado no mundo da programação de computadores. Agora, como relacionamos a linha usada para costurar roupas e a linha usada para programação de computador? As funções desempenhadas pelos dois threads são semelhantes aqui. Na roupa, a linha mantém o tecido unido e, do outro lado, na programação de computador, a linha prende o programa de computador e permite que o programa execute ações sequenciais ou várias ações ao mesmo tempo.

Threadé a menor unidade de execução 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 e compartilham a seção de código, seção de dados, etc. com outros threads. Esses threads também são conhecidos como processos leves.

Estados da linha

Para entender a funcionalidade dos threads em profundidade, precisamos aprender sobre o ciclo de vida dos threads ou os diferentes estados de thread. Normalmente, um thread pode existir em cinco estados distintos. Os diferentes estados são mostrados abaixo -

Novo Tópico

Um novo encadeamento inicia seu ciclo de vida no novo estado. No entanto, nesta fase, ainda não foi iniciado e não foram atribuídos quaisquer recursos. Podemos dizer que é apenas uma instância de um objeto.

Executável

Conforme o thread recém-nascido é iniciado, ele se torna executável, ou seja, aguardando para ser executado. Nesse estado, ele possui todos os recursos, mas o agendador de tarefas ainda não o programou para ser executado.

Corrida

Nesse estado, o encadeamento avança e executa a tarefa, que foi escolhida pelo planejador de tarefas para ser executada. Agora, o thread pode ir para o estado morto ou para o estado não executável / em espera.

Parado / em espera

Nesse estado, o encadeamento é pausado porque está aguardando a resposta de alguma solicitação de E / S ou pela conclusão da execução de outro encadeamento.

Morto

Um thread executável entra no estado finalizado quando completa sua tarefa ou então termina.

O diagrama a seguir mostra o ciclo de vida completo de um segmento -

Tipos de linha

Nesta seção, veremos os diferentes tipos de thread. Os tipos são descritos abaixo -

Threads de nível de usuário

Esses são threads gerenciados pelo usuário.

Nesse caso, o kernel de gerenciamento de encadeamentos não está ciente da existência de encadeamentos. A biblioteca de threads contém código para criar e destruir threads, para passar mensagens e dados entre threads, para agendar a execução de threads e para salvar e restaurar contextos de threads. O aplicativo começa com um único thread.

Os exemplos de threads de nível de usuário são -

  • Threads Java
  • Tópicos POSIX

Vantagens de Threads no nível do usuário

A seguir estão as diferentes vantagens de threads em nível de usuário -

  • A troca de threads não requer privilégios de modo Kernel.
  • O thread de nível de usuário pode ser executado em qualquer sistema operacional.
  • O agendamento pode ser específico do aplicativo no segmento de nível do usuário.
  • Os threads no nível do usuário são rápidos de criar e gerenciar.

Desvantagens de Threads no nível do usuário

A seguir estão as diferentes desvantagens de threads de nível de usuário -

  • Em um sistema operacional típico, a maioria das chamadas do sistema são bloqueadas.
  • O aplicativo multithread não pode tirar vantagem do multiprocessamento.

Threads de nível de kernel

Threads gerenciados pelo sistema operacional atuam no kernel, que é um núcleo do sistema operacional.

Nesse caso, o Kernel faz o gerenciamento de threads. Não há código de gerenciamento de encadeamento na área de aplicativo. Threads de kernel são suportados diretamente pelo sistema operacional. Qualquer aplicativo pode ser programado para ser multithread. Todos os threads em um aplicativo são suportados em um único processo.

O kernel mantém informações de contexto para o processo como um todo e para threads individuais dentro do processo. O agendamento pelo Kernel é feito com base em threads. O Kernel realiza a criação, programação e gerenciamento de threads no espaço do Kernel. Os threads do kernel geralmente são mais lentos para criar e gerenciar do que os threads do usuário. Os exemplos de threads de nível de kernel são Windows, Solaris.

Vantagens de threads de nível de kernel

A seguir estão as diferentes vantagens dos threads de nível de kernel -

  • O kernel pode agendar simultaneamente vários threads do mesmo processo em vários processos.

  • Se um thread em um processo for bloqueado, o Kernel pode agendar outro thread do mesmo processo.

  • As próprias rotinas do kernel podem ser multithread.

Desvantagens dos Threads de Nível de Kernel

  • Os threads do kernel geralmente são mais lentos para criar e gerenciar do que os threads do usuário.

  • A transferência de controle de um thread para outro dentro do mesmo processo requer uma mudança de modo para o Kernel.

Bloco de controle de linha - TCB

O Bloco de Controle de Thread (TCB) pode ser definido como a estrutura de dados no kernel do sistema operacional que contém principalmente informações sobre o thread. As informações específicas do thread armazenadas no TCB destacariam algumas informações importantes sobre cada processo.

Considere os seguintes pontos relacionados aos threads contidos no TCB -

  • Thread identification - É o id de thread exclusivo (tid) atribuído a cada novo thread.

  • Thread state - Ele contém as informações relacionadas ao estado (Executando, Executável, Não Executando, Morto) do thread.

  • Program Counter (PC) - Aponta para a instrução de programa atual da thread.

  • Register set - Ele contém os valores de registro do thread atribuídos a eles para cálculos.

  • Stack Pointer- Aponta para a pilha do segmento no processo. Ele contém as variáveis ​​locais no escopo do thread.

  • Pointer to PCB - Ele contém o ponteiro para o processo que criou esse segmento.

Relação entre processo e thread

Em multithreading, processo e thread são dois termos intimamente relacionados com o mesmo objetivo de tornar o computador capaz de fazer mais de uma coisa ao mesmo tempo. Um processo pode conter um ou mais threads, mas ao contrário, o thread não pode conter um processo. No entanto, ambos permanecem as duas unidades básicas de execução. Um programa, executando uma série de instruções, inicia o processo e encadea ambos.

A tabela a seguir mostra a comparação entre processo e thread -

Processo Fio
O processo é pesado ou exige muitos recursos. Thread é leve, o que requer menos recursos do que um processo.
A comutação de processos precisa de interação com o sistema operacional. A troca de thread não precisa interagir com o sistema operacional.
Em vários ambientes de processamento, cada processo executa o mesmo código, mas tem sua própria memória e recursos de arquivo. Todos os threads podem compartilhar o mesmo conjunto de arquivos abertos, processos filhos.
Se um processo for bloqueado, nenhum outro processo poderá ser executado até que o primeiro seja desbloqueado. Enquanto um encadeamento está bloqueado e esperando, um segundo encadeamento na mesma tarefa pode ser executado.
Vários processos sem usar threads usam mais recursos. Vários processos encadeados usam menos recursos.
Em vários processos, cada processo opera independentemente dos outros. Um thread pode ler, escrever ou alterar os dados de outro thread.
Se houver alguma mudança no processo pai, isso não afetará os processos filho. Se houver alguma mudança no thread principal, isso pode afetar o comportamento de outros threads desse processo.
Para se comunicar com processos irmãos, os processos devem usar comunicação entre processos. Threads podem se comunicar diretamente com outros threads desse processo.

Conceito de Multithreading

Como discutimos anteriormente, Multithreading é 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. De uma forma mais simples, podemos dizer que multithreading é a forma de realizar multitarefa utilizando o conceito de threads.

O conceito de multithreading pode ser entendido com a ajuda do exemplo a seguir.

Exemplo

Suponha que estejamos executando um processo. O processo pode ser para abrir a palavra MS para escrever algo. Nesse processo, um thread será atribuído para abrir a palavra MS e outro thread será necessário para escrever. Agora, suponha que se desejamos editar algo, então outro thread será necessário para fazer a tarefa de edição e assim por diante.

O diagrama a seguir nos ajuda a entender como vários threads existem na memória -

Podemos ver no diagrama acima que mais de um thread pode existir dentro de um processo, onde cada thread contém seu próprio conjunto de registros e variáveis ​​locais. Fora isso, todos os threads em um processo compartilham variáveis ​​globais.

Prós do Multithreading

Vejamos agora algumas vantagens do multithreading. As vantagens são as seguintes -

  • Speed of communication - O multithreading melhora a velocidade da computação porque cada núcleo ou processador lida com threads diferentes simultaneamente.

  • Program remains responsive - Permite que um programa permaneça responsivo porque um thread espera pela entrada e outro executa uma GUI ao mesmo tempo.

  • Access to global variables - No multithreading, todos os threads de um processo específico podem acessar as variáveis ​​globais e, se houver alguma alteração na variável global, ela também será visível para outros threads.

  • Utilization of resources - A execução de vários threads em cada programa faz melhor uso da CPU e o tempo ocioso da CPU diminui.

  • Sharing of data - Não há necessidade de espaço extra para cada encadeamento porque os encadeamentos em um programa podem compartilhar os mesmos dados.

Contras do multithreading

Vejamos agora algumas desvantagens do multithreading. As desvantagens são as seguintes -

  • Not suitable for single processor system - O multithreading tem dificuldade em obter desempenho em termos de velocidade de computação em um sistema de processador único em comparação com o desempenho em um sistema com vários processadores.

  • Issue of security - Como sabemos que todos os threads dentro de um programa compartilham os mesmos dados, portanto, sempre há um problema de segurança porque qualquer thread desconhecido pode alterar os dados.

  • Increase in complexity - O multithreading pode aumentar a complexidade do programa e a depuração se torna difícil.

  • Lead to deadlock state - O multithreading pode levar o programa a um risco potencial de atingir o estado de deadlock.

  • Synchronization required- A sincronização é necessária para evitar exclusão mútua. Isso leva a mais memória e utilização da CPU.