O caso
Um navegador. Doze entradas. E o sistema de pedidos, uma só.
O Isaac abriu o gerenciador de tarefas e viu o navegador listado doze vezes. O sistema de pedidos da loja aparecia uma só, mas atendia dezenas de clientes ao mesmo tempo.
Dois programas, dois jeitos de organizar o trabalho. O que o sistema operacional entende por "um programa rodando"?
Este post parte do Kernel: é ele quem cria e acompanha tudo o que está descrito aqui.
O problema
Um programa no disco não faz nada
Um programa é um arquivo, guardado no disco. Para ele rodar, o sistema precisa carregá-lo na memória, dar a ele um pedaço do processador e acompanhar o que ele faz. E surgem duas necessidades ao mesmo tempo:
- Isolar: dois programas não podem estragar a memória um do outro.
- Fazer várias coisas: um mesmo programa, como o sistema de pedidos, precisa atender muitos clientes sem fazer um esperar o outro.
A solução
Processo: um programa em execução
Um processo é um programa em execução. O programa é a receita no papel, e o processo é a cozinha funcionando. O kernel guarda, para cada processo, uma ficha com tudo o que precisa saber:
- o PID (process ID), um número que identifica o processo;
- o estado (rodando, esperando…);
- a memória que ele pode usar, separada da dos outros;
- os arquivos abertos e os valores dos registradores do processador.
Essa ficha se chama bloco de controle do processo (process control block, PCB).
Como um processo nasce
Nos sistemas Unix, como o Linux e o macOS, um processo novo nasce em dois passos:
- O
forkcria um processo filho, uma cópia do processo que o chamou (o pai). Para não copiar tudo de uma vez, o Linux usa o copy-on-write: pai e filho compartilham a memória até um deles escrever, e só aí a parte alterada é copiada. - O
exectroca o programa do filho por outro. É assim que o terminal abre ols: faz umfork, e o filho executa ols.
O que o processo está fazendo
Em cada instante, um processo está em um destes estados:
| Estado | O que significa |
|---|---|
| Pronto (ready) | Tem tudo para rodar e espera a sua vez no processador |
| Executando (running) | Está usando o processador agora |
| Bloqueado (blocked, ou waiting) | Espera algo para continuar, como a resposta do disco ou da rede |
O kernel alterna os processos entre esses estados tão rápido que parece que todos rodam ao mesmo tempo. Cada troca exige guardar o estado do que sai e restaurar o do que entra: é a troca de contexto (context switch), que custa tempo.
Dentro do processo
Thread: várias linhas de execução
Uma thread é uma linha de execução dentro de um processo. Todo processo tem pelo menos uma, e pode ter várias. As threads de um mesmo processo:
- compartilham a memória e os arquivos abertos do processo;
- têm, cada uma, a sua pilha (stack) e os seus registradores, porque cada uma está num ponto diferente do código.
O processo é a loja do Isaac, com o seu balcão, o seu estoque e o seu caixa. As threads são os funcionários: todos trabalham na mesma loja e mexem no mesmo estoque, e cada um está fazendo uma tarefa diferente. Outra loja é outro processo: tem o seu próprio estoque, e ninguém de uma entra no estoque da outra.
Como as threads dividem a memória, criar uma e trocar entre elas é mais barato do que com processos. O preço é o risco: duas threads mexendo no mesmo dado ao mesmo tempo podem se atrapalhar, um problema que vai aparecer nos posts sobre concorrência.
Não confunda
Processo × thread
Processo (process)
“Preciso de isolamento forte entre as partes?”
- Exemplo
- Cada aba do navegador, para que o travamento de uma não derrube as outras.
- Foco
- Memória própria, mais caro de criar, e a falha de um não afeta os outros.
Thread
“Preciso de várias tarefas que trabalhem nos mesmos dados?”
- Exemplo
- O sistema de pedidos, atendendo vários clientes com uma thread para cada pedido.
- Foco
- Compartilha a memória, é mais leve, e a falha de uma pode derrubar o processo todo.
Na prática
Onde isso aparece
Navegador (processos por aba)
Os navegadores modernos usam processos separados para isolar as abas e as extensões.
No computador do Isaac: as doze entradas do navegador.
Servidor com threads (thread pool)
Um servidor mantém um grupo de threads prontas, e cada pedido usa uma delas.
Na loja: o sistema de pedidos atendendo dezenas de clientes.
Observar processos e threads (ps, top)
No Linux, ps -eLf lista os processos e as suas threads, e top mostra o que está usando o processador.
| Situação | Escolha |
|---|---|
| Programas que não podem se atrapalhar, ou código de terceiros | Processos |
| Muitas tarefas que leem e escrevem os mesmos dados | Threads |
| Uma falha não pode derrubar o resto | Processos |
| A criação precisa ser rápida e barata | Threads |
Termos-chave
Seis termos para fixar
Toque no cartão para ver a definição.
Teste rápido
Três perguntas, estilo prova
01
O que as threads de um mesmo processo compartilham?
02
Num sistema Unix, o que a chamada fork faz?
03
Uma thread acessa uma região inválida da memória e o programa é encerrado. O que acontece com as demais threads do processo?
Processo e thread respondem a duas necessidades diferentes: o processo isola um programa dos outros, e a thread permite que um programa faça várias coisas com os mesmos dados. Escolher entre eles é escolher entre isolamento e economia, e é isso que explica por que o navegador usa processos e o servidor do Isaac usa threads.