oi!! (≧◡≦) chegamos no coração do sistema operacional: processos e threads. se o SO é um restaurante, os processos são os clientes e o escalonador é o maître que organiza as mesas. sem ele, vira panelaço. bora entender tudo!! ☆~(ゝ。∂)
1. Processo: Programa em Execução
a diferença entre programa e processo é simples: programa é o arquivo no disco (estático), processo é o programa rodando na memória (dinâmico). é a diferença entre a receita do bolo e o bolo assando no forno. (。◕‿◕。)
um processo precisa de:
- Espaço de endereçamento: memória própria (código, dados, pilha, heap).
- Recursos: arquivos abertos, dispositivos alocados, semáforos.
- Estado do processador: valores dos registradores, contador de programa (PC).
tudo isso fica guardado numa estrutura chamada PCB (Process Control Block), ou BCP (Bloco de Controle de Processo). é a "ficha cadastral" do processo. sem ela, o SO não sabe quem é quem. (¬‿¬)
identificador do processo (PID), estado atual, contador de programa, registradores, limites de memória, lista de arquivos abertos, prioridade, informação de accounting (tempo de CPU usado)... é praticamente um RG, CPF e histórico médico do processo. (✿◠‿◠)
2. Estados de um Processo
um processo não fica o tempo todo executando. ele passa por vários estados durante a vida:
- Novo: acabou de ser criado. ainda não foi admitido pelo SO.
- Pronto: tá esperando só o processador ficar livre. tipo fila do banco. (。•̀ᴗ-)✧
- Executando: usando a CPU no momento. é o queridinho da vez.
- Esperando (Bloqueado): parou porque precisa de algo: leitura de disco, entrada do teclado, resposta da rede. não adianta dar CPU pra ele agora.
- Terminado: acabou a execução. o SO limpa a bagunça e libera recursos.
a transição mais comum é: pronto → executando → esperando → pronto → executando → terminado. mas pode ter várias idas e vindas entre pronto e executando, dependendo do escalonamento. (⌐■_■)
Novo → Pronto ↔ Executando → Terminado
Executando ↓ Esperando ↑ Pronto
executando vai pra esperando quando precisa de E/S. esperando volta pra pronto quando a E/S termina. pronto vai pra executando quando o escalonador escolhe ele. simples!! ヾ(^-^)ノ
3. Threads: Processos Dentro de Processos
um processo pode ter várias threads (linhas de execução). pensa no processo como uma fábrica: a thread é uma linha de montagem dentro dela. threads de um mesmo processo compartilham memória e recursos, mas cada uma tem seu próprio contador de programa, registradores e pilha. (•̀ᴗ•́)و
vantagens de threads:
- Responsividade: enquanto uma thread espera E/S, outra continua trabalhando. a interface não trava.
- Economia de recursos: criar thread é mais barato que criar processo. não precisa duplicar todo o espaço de endereçamento.
- Compartilhamento: threads do mesmo processo acessam as mesmas variáveis. comunicação é trivial.
- Escalabilidade: aproveita múltiplos núcleos. cada núcleo roda uma thread diferente. boom, paralelismo!! (☆▽☆)
existem threads de usuário (gerenciadas por biblioteca, o kernel nem sabe que existem) e threads de kernel (o kernel gerencia direto, mais pesado mas permite verdadeiro paralelismo). hoje em dia a maioria dos sistemas usa threads de kernel ou um modelo híbrido.
threads compartilham memória. se uma thread altera uma variável enquanto outra lê, pode dar problema. isso chama condição de corrida. a gente vê como resolver isso no Tema 4. por enquanto, só saiba que mais threads ≠ mais felicidade se não souber usar. (╥﹏╥)
4. Escalonamento de Processos (Scheduling)
o escalonador (scheduler) é o cara que decide qual processo da fila de prontos vai usar a CPU. é tipo o porteiro de balada: escolhe quem entra, quem espera, e quem já tá lá dentro há tempo demais e precisa sair. ( ͡~ ͜ʖ ͡°)
existem três níveis de escalonamento:
- Longo prazo: decide quais processos entram na memória (admissão). pouco usado hoje em dia.
- Médio prazo: faz swapping: tira processos da memória pro disco e depois traz de volta. ajuda quando a RAM tá cheia.
- Curto prazo: decide qual processo pronto executa agora. é o mais rápido e executa milhares de vezes por segundo.
5. Algoritmos de Escalonamento
vamos aos algoritmos clássicos. segura aí. (ノ◕ヮ◕)ノ*:・゚✧
5.1 FCFS (First-Come, First-Served)
o primeiro a chegar é o primeiro a ser atendido. fila simples, justa, mas com um problema enorme: efeito comboio. se o primeiro processo é longo, todo mundo espera. imagina ficar atrás da pessoa que tem carrinho cheio no mercado e vc só quer uma água. (T_T)
5.2 SJF (Shortest Job First)
atende o processo mais curto primeiro. teoricamente minimiza o tempo médio de espera. mas tem dois probleminhas:
- precisa saber de antemão quanto tempo cada processo vai durar. e adivinhar o futuro é difícil. ( ̄ω ̄)
- processos longos podem sofrer starvation (fome): se sempre chega um processo curto, o longo nunca executa.
5.3 Round Robin (RR)
cada processo ganha uma fatia de tempo (time quantum, tipo 10ms ou 100ms). quando acaba o tempo, o processo vai pro final da fila e o próximo executa. é justo, simples, e funciona bem pra sistemas interativos. se o quantum for muito curto, vira só troca de contexto. se for muito longo, vira FCFS. ajustar é a arte. (•̀ᴗ•́)و
5.4 Prioridades
cada processo tem uma prioridade. o de maior prioridade executa primeiro. pode ser preemptivo (se chegar um mais prioritário, interrompe o atual) ou não preemptivo (só quando o atual libera). problema: starvation de processos de baixa prioridade. solução comum: envelhecimento (aging) — quanto mais tempo esperando, mais a prioridade sobe. tipo fila de idoso no banco. (。♥‿♥。)
5.5 Filas Multinível
divide os processos em várias filas, cada uma com seu algoritmo. exemplo: fila de sistemas (alta prioridade, RR curto), fila interativa (RR médio), fila batch (FCFS, baixa prioridade). processos não mudam de fila. Multinível com realimentação permite mudar de fila: se um processo usa muito CPU, desce de prioridade. se é interativo, sobe. o Linux já usou abordagens semelhantes no passado, mas o scheduler atual (CFS — Completely Fair Scheduler) organiza processos numa árvore e distribui tempo de forma justa. a ideia de prioridades dinâmicas ainda existe por baixo. (。•̀ᴗ-)✧
FCFS: simples, mas injusto com processos curtos.
SJF: eficiente, mas imprevisível e pode causar starvation.
Round Robin: justo, ótimo pra interativos, mas depende do quantum.
Prioridades: flexível, mas exige cuidado com starvation.
Multinível: complexo, mas se adapta a diferentes tipos de carga. (✧≖‿≖)
6. Troca de Contexto
a troca de contexto (context switch) é quando o SO pausa um processo e coloca outro pra executar. ele salva o estado do processo antigo no PCB, carrega o estado do novo, e manda ver. é tipo trocar de jogador num jogo: anota o estado do que tava jogando, passa a bola pro outro. (ノ◕ヮ◕)ノ*:・゚✧
o problema: troca de contexto consome tempo. não é processamento útil, é overhead. se o quantum for muito curto, vc passa mais tempo trocando contexto do que executando. é por isso que existe um valor ideal pro quantum, geralmente entre 10ms e 100ms, dependendo do hardware e da carga.
no Linux, a troca de contexto leva alguns microssegundos. parece pouco, mas num servidor com milhares de processos, faz diferença. por isso existem tecnologias como coroutines e fibers: trocam contexto no espaço do usuário, sem syscall, muito mais rápido. Go, Kotlin e Rust usam isso bastante. (¬‿¬)
7. Considerações Finais
processos e threads são os atores principais de qualquer sistema operacional. o escalonador é o diretor que organiza o espetáculo. escolher o algoritmo certo depende do que vc precisa:
- sistema interativo? Round Robin é uma boa.
- batch processing? SJF ou prioridades.
- tempo real? precisa de garantias duras, não só estatísticas.
- servidor web? filas multinível com realimentação.
entender isso ajuda não só em prova, mas também quando vc precisa tunar uma aplicação, escolher um servidor, ou entender por que seu computador trava quando abre 200 abas no Chrome. spoiler: é culpa dos processos, não do mouse. ( ͡~ ͜ʖ ͡°)
no Linux, use top, htop ou ps pra ver processos e threads em tempo real. no Windows, o Gerenciador de Tarefas mostra isso. quando vc entende o que tá vendo, para de achar que computador é mágica. é só processos sendo escalonados muito rápido. (◍•ᴗ•◍)
fechou, senpai? (☆▽☆) até o próximo tema!! ٩(◕‿◕)۶