As operações mais simples realizadas por um computador, como somar dois números ou acessar um local na memória, são denominadas instruções. Um programa é uma coleção ordenada dessas instruções. Programas permitem que o computador execute tarefas complexas e geralmente são armazenados em arquivos executáveis, funcionando como um guia que o sistema segue para produzir resultados.
A diferença entre programa e processo reside na execução: um processo é a instância ativa de um programa, similar a preparar uma refeição seguindo uma receita. O mesmo programa pode originar múltiplos processos, cada um com seu próprio espaço de memória e interfaces de E/S. O sistema operacional gerencia processos, alocando recursos e mantendo informações, oferecendo um ambiente estruturado para sua execução.
Observando Processos
O comando ps é usado para listar processos em execução. Por exemplo, ps -e -o pid,name,command exibe:
PID NAME COMMAND 1 systemd /sbin/init 1234 bash -bash 5678 terminal ps -e -o pid,name,command
</div>Cada linha representa um processo, com colunas para PID (identificador único), nome e comando associado. Entradas entre colchetes indicam componentes do kernel, que podem ser ignorados.
O processo com PID 1, tipicamente `systemd` ou `init`, é criado durante a inicialização do sistema e persiste até o desligamento, sendo fundamental para a operação do Linux.
### Criação de Processos
Durante a inicialização, o kernel gera apenas o processo raiz. Outros processos são criados via `fork`, uma chamada de sistema que duplica o processo pai. O kernel aloca novo espaço de memória para o filho e copia os dados do pai, permitindo execução concorrente.
O processo pai recebe o PID do filho, enquanto o filho recebe 0. Usando o PPID (PID do pai), é possível rastrear a hierarquia até o processo inicial, formando uma estrutura em árvore. Exemplo de visualização hierárquica:
<div>```
$ pgrep -a --list-full
1234 /sbin/init
5678 /usr/bin/sudo -i
9012 /bin/bash
3456 ps pgrep -a --list-full
systemd(1)─┬─NetworkManager(567)─┬─dhclient(890) │ └─{NetworkManager}(568) ├─cron(234) └─apache2(678)─┬─apache2(679) └─apache2(680)
</div>Após o `fork`, programas frequentemente usam `exec` para substituir a imagem do processo filho, permitindo a execução de programas diferentes.
### Término de Processos
Quando um processo filho finaliza, ele notifica o pai e libera recursos, mantendo um código de saída no kernel. O pai deve invocar `wait` para recuperar essa informação e limpar o kernel. Se o pai terminar primeiro, o filho se torna órfão e é adotado pelo processo inicial.
Se o pai não chamar `wait`, o filho se torna um zumbi, ocupando recursos no kernel. Acúmulos de zumbis podem degradar o desempenho do sistema.
### Processos e Threads
No Linux, threads são implemnetadas como processos leves que compartilham espaço de memória e recursos de E/S. Diferentemente de outros sistemas UNIX, onde threads e processos são distinções claras, no Linux a unidade básica de execução é sempre o processo.