Nesta aula, mergulhamos no conceito de processos em sistemas operacionais. Um processo é essencialmente um programa em execução, mas envolve muito mais do que apenas o código: ele carrega consigo um contexto completo, incluindo registradores, contador de programa, pilha e espaço de endereçamento. Compreender como o sistema operacional gerencia múltiplos processos é fundamental para entender o funcionamento de qualquer sistema computacional moderno.

O que é um processo?

Um processo pode ser definido como uma unidade de trabalho em um sistema operacional. Diferente de um programa (que é uma entidade passiva armazenada em disco), o processo é uma entidade ativa que possui um estado de execução. Cada processo é representado internamente por uma estrutura chamada bloco de controle de processo (Process Control Block – PCB), que contém todas as informações necessárias para gerenciar sua execução:

  • Identificador único (PID)
  • Estado atual do processo
  • Registradores da CPU
  • Contador de programa
  • Informações de escalonamento
  • Informações de gerenciamento de memória
  • Informações de I/O

O PCB é criado quando o processo é iniciado e atualizado continuamente pelo sistema operacional durante sua execução.

Estados de um processo

Ao longo de sua vida, um processo transita entre diferentes estados. O modelo clássico de cinco estados é amplamente utilizado:

  1. Novo (New): O processo está sendo criado.
  2. Pronto (Ready): O processo está carregado na memória e aguarda a vez de usar a CPU.
  3. Executando (Running): O processo está sendo executado pela CPU.
  4. Bloqueado (Waiting/Blocked): O processo está aguardando a ocorrência de algum evento (como I/O ou sinal) para continuar.
  5. Terminado (Terminated): O processo concluiu sua execução.

As transições entre esses estados são controladas pelo escalonador e pelo dispatcher do sistema operacional.

Escalonamento de processos

O escalonamento de CPU é a atividade que decide qual dos processos prontos será executado. O módulo responsável é o escalonador de curto prazo (short‑term scheduler). Existem duas categorias principais de escalonamento: preemptivo e não preemptivo.

  • Não preemptivo (cooperativo): o processo executa até bloquear ou terminar voluntariamente.
  • Preemptivo: o sistema operacional pode interromper o processo a qualquer momento para dar a CPU a outro processo.

Alguns algoritmos clássicos de escalonamento:

Algoritmo Preemptivo? Descrição Problemas
FCFS (First‑Come, First‑Served) Não Executa na ordem de chegada Efeito comboio, tempo médio de espera alto
SJF (Shortest Job First) Não / Sim (SRTF) Executa o processo com menor próximo surto de CPU Impossível saber o surto antecipadamente; pode causar starvation
Round Robin Sim Distribui um quantum de tempo para cada processo em ordem circular Quantum muito pequeno → muitas trocas; muito grande → interativo lento
Escalonamento por Prioridade Sim / Não Processos com prioridade mais alta executam primeiro Starvation de processos de baixa prioridade (solucionável com envelhecimento)

A escolha do algoritmo depende do ambiente: sistemas interativos favorecem Round Robin; sistemas batch podem usar FCFS ou SJF.

Troca de contexto (Context Switch)

Quando o escalonador decide interromper um processo e iniciar outro, ocorre uma troca de contexto. O sistema operacional salva o estado atual do processo (registradores, contador de programa, etc.) no seu PCB e carrega o estado do próximo processo. Essa operação tem um custo em tempo de CPU, pois envolve manipulação de estruturas de dados e geralmente exige a invalidação de caches. Sistemas operacionais modernos otimizam esse processo ao máximo, mas trocas excessivas (por exemplo, com quantum muito pequeno no Round Robin) podem degradar o desempenho.

Concorrência e paralelismo

Em sistemas com um único núcleo, a ilusão de execução simultânea é obtida por meio da concorrência: o sistema intercala rapidamente a execução dos processos, dando a impressão de paralelismo. Já em sistemas multicore, é possível o paralelismo real, com múltiplos processos executando ao mesmo tempo em núcleos diferentes.

No entanto, a concorrência traz desafios: acesso concorrente a recursos compartilhados pode levar a condições de corrida (race conditions). Para evitar isso, são empregados mecanismos de exclusão mútua, como semáforos, mutexes e monitores.

Comunicação entre processos (IPC)

Muitas vezes, processos precisam trocar dados ou se sincronizar. O sistema operacional oferece diversos mecanismos de comunicação entre processos (IPC – Inter‑Process Communication):

  • Pipe: canal unidirecional de comunicação entre processos relacionados.
  • FIFO (named pipe): similar ao pipe, mas permite comunicação entre processos não relacionados via um arquivo especial.
  • Memória compartilhada: região de memória acessível por múltiplos processos; requer sincronização explícita.
  • Filas de mensagens: troca de mensagens através de uma fila gerenciada pelo kernel.
  • Socket: usado para comunicação entre processos em diferentes máquinas, mas também localmente.

Cada mecanismo tem suas vantagens e cenários de uso. A memória compartilhada é a mais rápida, mas exige controle de concorrência; as filas de mensagens são mais seguras, embora introduzam overhead.

Exemplo: criação de processos em Python

A biblioteca multiprocessing do Python permite criar processos de forma simples:

import multiprocessing
import os

def task(name):
    print(f"Processo {name} (PID: {os.getpid()}) em execução")

if __name__ == "__main__":
    p1 = multiprocessing.Process(target=task, args=("A",))
    p2 = multiprocessing.Process(target=task, args=("B",))
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print("Ambos os processos finalizaram")

Este script cria dois processos filhos que executam a função task concorrentemente. A chamada join() garante que o processo principal aguarde o término de cada filho.

Perguntas Frequentes

Qual a diferença entre processo e thread?

Um processo possui seu próprio espaço de endereçamento, enquanto uma thread compartilha o mesmo espaço de endereçamento com outras threads do mesmo processo. Threads são mais leves e a comunicação entre elas é mais eficiente, mas exigem cuidado com acesso concorrente a dados globais.

O que é starvation em escalonamento?

Starvation (ou inanição) ocorre quando um processo nunca recebe tempo de CPU porque outros processos com prioridade maior sempre são escolhidos. Técnicas como envelhecimento (aging) aumentam gradualmente a prioridade de processos que esperam há muito tempo para evitar esse problema.

Como funciona o algoritmo Round Robin?

Round Robin atribui a cada processo um intervalo fixo de tempo chamado quantum. A fila de prontos é tratada como circular. Se um processo não termina dentro do quantum, a CPU é retirada dele e vai para o próximo. É justo e evita starvation, mas o desempenho depende da escolha adequada do quantum.

Nesta aula, consolidamos os fundamentos do gerenciamento de processos: desde a representação interna (PCB) até os mecanismos de comunicação e sincronização. Esses conceitos são a base para o projeto e a análise de sistemas operacionais modernos, e serão explorados em maior profundidade nas próximas aulas.