Threads em Sistemas Operacionais
Durante nossa jornada pela Engenharia de Software, passamos rapidamente da escrita de scripts sequenciais para a necessidade de sistemas que realizam mĂșltiplas tarefas simultaneamente. Para entender como um navegador web pode baixar uma imagem, responder aos cliques dos usuĂĄrios e renderizar um vĂdeo ao mesmo tempo, precisamos falar sobre Threads.
O que Ă© um(a) thread?
Em termos acadĂȘmicos, uma thread (ou linha de execução) Ă© a menor unidade de processamento que pode ser agendada por um sistema operacional. Ela reside dentro do contexto de um processo.
De acordo com Tanenbaum (2016, p. 53), enquanto um processo Ă© uma maneira de agrupar recursos relacionados (como espaço de endereçamento, arquivos abertos e sinais), a thread Ă© a entidade executada na CPU. Podemos imaginar que se o processo Ă© o “contĂȘiner” de recursos, a thread Ă© o “fluxo” de execução de instruçÔes.
Processos vs. Threads
Diferentemente dos processos, que são isolados uns dos outros por questÔes de segurança e integridade, as threads de um mesmo processo compartilham o mesmo espaço de memória (heap). No entanto, cada thread possui seu próprio:
- Contador de Programa (PC): para saber qual instrução executar a seguir.
- Registradores: para armazenar variĂĄveis de trabalho atuais.
- Pilha (stack): para gerenciar chamadas de funçÔes e variåveis locais.
Na Figura 1 podemos ver um desenho esquemĂĄtico que representa o conceito de ambiente monothread, ou seja, cada processo (cĂrculo) contĂ©m apenas um fluxo – thread – para operação (retĂąngulo dentro do cĂrculo).

Fonte: Machado e Maia (2014).
Em contrapartida, na Figura 2 encontramos o desenho esquemĂĄtico do que seria um ambiente multithread. Um processo qualquer (cĂrculo) contĂ©m trĂȘs fluxos – threads – de operação (retĂąngulos) em seu ambiente, compartilhando alguns recursos com esses threads.

Fonte: Machado e Maia (2014).
CaracterĂsticas fundamentais
As threads possuem propriedades que as tornam indispensĂĄveis para o desenvolvimento de software moderno:
- Compartilhamento de recursos: elas compartilham o cĂłdigo, os dados e os recursos do sistema operacional (como arquivos abertos) do processo pai.
- Economia (lightweight): criar uma thread Ă© muito mais “barato” em termos de processamento e memĂłria do que criar um processo novo, pois nĂŁo hĂĄ necessidade de replicar todo o espaço de endereçamento.
- ConcorrĂȘncia e paralelismo: em sistemas com mĂșltiplos nĂșcleos (multi-core), threads diferentes podem ser executadas em nĂșcleos diferentes simultaneamente (paralelismo real). Em nĂșcleos Ășnicos, o SO alterna entre elas tĂŁo rĂĄpido que cria a ilusĂŁo de simultaneidade (concorrĂȘncia).
A Figura 3 traz uma representação mais ampla da separação de fluxos de trabalho dentro de um pseudocódigo com vårios threads (Thread_1, Thread_2 e Thread_3) que realizam tarefas independentemente dentro do código geral.

Fonte: Machado e Maia (2014).
BenefĂcios e trade-offs
Ă importante sempre reforçamos que nĂŁo existe “bala de prata” na computação. Toda escolha envolve trocas. Neste caso, a introdução de threads traz uma complexidade exponencial ao projeto. Portanto, falemos sobre os prĂłs e os contras dessa tĂ©cnica.
BenefĂcios
- Responsividade: em aplicaçÔes de interface grĂĄfica (GUI), uma thread pode processar a entrada do usuĂĄrio enquanto outra realiza um cĂĄlculo pesado em segundo plano, evitando que a tela “trave”.
- Utilização de arquiteturas multi-core: permite que a aplicação utilize todo o poder de processamento do hardware disponĂvel.
- Comunicação eficiente: como compartilham a mesma memória, a comunicação entre threads (inter-thread communication) é mais råpida que a comunicação entre processos.
Trade-offs
- CondiçÔes de corrida (Race conditions): quando duas threads tentam alterar o mesmo dado simultaneamente, o resultado final depende da ordem de execução, que Ă© imprevisĂvel. Isso exige o uso de mecanismos de sincronização como Mutexes e SemĂĄforos.
- Deadlocks (Impasses): ocorre quando uma Thread A espera por um recurso reservado pela Thread B, enquanto a Thread B espera por um recurso reservado pela Thread A. Logo, ambas param para sempre.
- Dificuldade de debugging: erros em sistemas multithread sĂŁo frequentemente nĂŁo-determinĂsticos (difĂceis de reproduzir), conhecidos como Heisenbugs.
- Overhead de troca de contexto: se houver threads demais para poucos nĂșcleos, o sistema gasta mais tempo alternando entre elas do que executando o cĂłdigo propriamente dito.
ConsideraçÔes finais
Dominar threads Ă© o que separa um programador que apenas “faz funcionar” de um Engenheiro de Software que projeta sistemas robustos. Como afirma Silberschatz, Galvin e Gagne (2015), o projeto de aplicaçÔes multithreaded tornou-se uma necessidade absoluta com a estagnação das velocidades de clock e o foco da indĂșstria em mĂșltiplos nĂșcleos de processamento.
Por isso, continue lendo os artigos deste site, alĂ©m de consultar as fontes de referĂȘncia utilizadas. Deixamos para os caros leitores os vĂdeos abaixo onde explicamos um pouco mais sobre threads e fizemos atĂ© um exemplo de cĂłdigo em linguagem C criando um ambiente multithread. Obrigado pela leitura e bons estudos.
ReferĂȘncias
MACHADO, Francis Berenger; MAIA, Luiz Paulo. Arquitetura de sistemas operacionais. 5ÂȘ ed. Rio de Janeiro: LTC, 2014.
SILBERSCHATZ, Abraham; GALVIN, Peter B.; GAGNE, Greg. Sistemas Operacionais com Java. 9. ed. Rio de Janeiro: LTC, 2015.
TANENBAUM, Andrew S. Sistemas Operacionais Modernos. 4. ed. SĂŁo Paulo: Pearson Education do Brasil, 2016.


