Ciência da computação

Processos vs. threads: essencial na entrevista

Ao abrir o Gerenciador de Tarefas, você vê processos; ao ler documentação de desenvolvimento, aparecem threads. Ambos parecem ser “algo que executa”, mas qual é exatamente a diferença?

5 min de leitura
Imagem de capa de Processos vs. threads: essencial na entrevista

Ao abrir o Gerenciador de Tarefas, você vê processos; ao ler documentação de desenvolvimento, aparecem threads. Ambos parecem ser “algo que executa”, mas qual é exatamente a diferença?

Se fosse para escolher a pergunta mais comum em entrevistas técnicas, seria esta: “Explique a diferença entre um processo e uma thread.”

O motivo é simples: uma única pergunta permite avaliar estrutura de memória, sistemas operacionais e concorrência de uma vez.

Neste artigo, vamos explicar a diferença entre os dois pela perspectiva da estrutura de memória e até onde vale chegar em uma resposta de entrevista.

Vamos começar pelo essencial.

  1. Processo: um programa em execução. Recebe um espaço de memória independente completo.
  2. Thread: um fluxo de execução dentro de um processo. Tem sua própria stack e compartilha o restante.
  3. Por compartilharem memória, as threads são leves e rápidas, mas também podem gerar condições de corrida de dados.
  4. Processos são isolados e seguros, mas, em contrapartida, são mais pesados e têm comunicação mais trabalhosa.

Processo: um programa em execução

Um programa é um bloco de código armazenado no disco. Ele ainda não está fazendo nada.

No momento em que você o executa, o sistema operacional o carrega na memória e se prepara para atribuir tempo de CPU. Esse “programa em execução” é um processo.

O sistema operacional fornece a cada processo um espaço de memória virtual independente completo. Ele tem quatro áreas principais.

Área Conteúdo
Código (Text) Código de máquina a ser executado
Dados (Data) Variáveis globais e estáticas
Heap Memória alocada dinamicamente em tempo de execução
Stack Informações de chamadas de função e variáveis locais

A palavra importante aqui é “independente”. O processo A não pode examinar a memória do processo B. O sistema operacional bloqueia isso na origem.

Por isso, um processo pode falhar enquanto os outros continuam funcionando. O Chrome cria um processo separado para cada aba por esse motivo. Se uma aba travar, o navegador inteiro continua vivo.


Thread: um fluxo de execução dentro de um processo

Uma thread é a unidade de fluxo de execução que realmente executa código dentro de um processo. Todo processo começa com pelo menos uma thread, a thread principal.

O ponto central é o que é compartilhado. Threads do mesmo processo compartilham as áreas de código, dados e heap, enquanto cada uma tem sua própria stack.

Somente a stack é separada; código, dados e heap são compartilhados.
Somente a stack é separada; código, dados e heap são compartilhados.

O motivo para cada thread ter sua própria stack é claro: ela registra qual função está sendo executada e até onde avançou, portanto cada fluxo de execução precisa de uma.

Como o heap é compartilhado, as threads podem trocar dados imediatamente por meio de uma variável. Não é necessário um procedimento separado de comunicação.


Por que usar threads: uma questão de custo

Você pode pensar: “Se quero fazer várias coisas ao mesmo tempo, por que não iniciar vários processos?”. O problema é o custo.

Custo de criação. Criar um processo exige preparar um espaço de memória independente completo. Para uma thread, basta adicionar uma stack.

Custo de troca. Quando a CPU muda para outro processo, precisa substituir todo o mapa de memória (troca de contexto). Trocar entre threads do mesmo processo é muito mais leve.

Custo de comunicação. Para trocar dados, processos precisam usar IPC (comunicação entre processos), como pipes ou sockets. Threads podem simplesmente ler a mesma variável.

Em resumo, uma thread é a unidade para fazer várias coisas ao mesmo tempo com baixo custo.


Nada é de graça: condições de corrida de dados

Todas as vantagens das threads vêm do compartilhamento de memória, e sua maior fraqueza surge exatamente do mesmo ponto.

Se duas threads escreverem na mesma variável ao mesmo tempo, o resultado será imprevisível. Isso é uma condição de corrida de dados.

Até um código de uma linha, como count += 1, envolve internamente três etapas —ler, somar e escrever—, então threads sobrepostas podem fazer um incremento desaparecer na prática.

Por isso são necessárias ferramentas de sincronização, como locks e semáforos. Usá-las incorretamente abre outro pesadelo: deadlocks.

Processos não têm esse problema porque sua memória já é isolada desde o início. É uma troca entre segurança e eficiência.

Uma condição de corrida de dados começa no instante em que várias threads acessam a memória compartilhada ao mesmo tempo.
Uma condição de corrida de dados começa no instante em que várias threads acessam a memória compartilhada ao mesmo tempo.

Pela perspectiva de um desenvolvedor iOS

No iOS, um app é um processo. Por causa do sandbox, um app não pode acessar a memória de outro. O isolamento de processos descrito acima se aplica diretamente.

Dentro de um app, a thread principal cuida da UI, enquanto operações de rede e cálculos pesados são enviados para outras threads. A regra “atualize a UI na thread principal” se baseia diretamente no conceito de thread.

No entanto, criar threads diretamente é incomum no desenvolvimento moderno para iOS. Envie o trabalho para uma fila do GCD ou para um Task do Swift Concurrency, e o sistema o atribuirá automaticamente a partir de um pool de threads. A abstração subiu um nível, mas as threads continuam rodando por baixo.


Como responder na entrevista

É melhor começar com uma resposta de uma frase.

“Um processo é uma unidade de execução com um espaço de memória independente, enquanto uma thread é um fluxo de execução dentro de um processo que tem sua própria stack e compartilha o restante da memória.”

As perguntas seguintes são quase previsíveis: “O que uma thread compartilha e o que mantém separado?” (somente a stack), “Por que threads são mais leves?” (custos de criação, troca e comunicação) e “Qual é o problema de compartilhar?” (condições de corrida de dados e sincronização). Cobrir isso já atende ao esperado.

Acrescente um exemplo real, como abas do Chrome ou o sandbox do iOS, e você transmitirá compreensão em vez de memorização.


Resumo

  • Um processo é um programa em execução e recebe do sistema operacional um espaço de memória independente (código, dados, heap e stack).
  • Uma thread é um fluxo de execução dentro de um processo; tem sua própria stack e compartilha código, dados e heap.
  • Threads são leves porque os custos de criação, troca e comunicação são baixos, mas a memória compartilhada traz risco de condições de corrida de dados.
  • Processos são isolados e seguros, mas pesados, e precisam de IPC para se comunicar.
  • No iOS, um app é um processo, enquanto GCD e Task são abstrações construídas sobre threads.
  • Estrutura da resposta: definição em uma frase → escopo compartilhado → diferença de custos → condições de corrida de dados