Programação Concorrente, Escalonamento e Processos
🧵 1. Concorrência
- Concorrência → execução simultânea de múltiplos fluxos de instruções.
- Threads → compartilham o mesmo espaço de endereçamento.
- Processos → possuem espaços separados de memória.
👥 2. Processo vs Thread
- Processo → unidade de execução com memória isolada.
- Thread → fluxo leve de execução que compartilha recursos com outras threads do mesmo processo.
- Threads são mais leves e rápidas → indicadas para tarefas simultâneas dentro de um mesmo processo.
⚠️ 3. Condição de Corrida (Race Condition)
Ocorre quando dois ou mais processos ou threads acessam um recurso compartilhado ao mesmo tempo e o resultado final depende da ordem de execução → ordem importa.
🔄 4. Semáforos
São estruturas de controle usadas para sincronizar o acesso à seção crítica → ajudam a garantir exclusão mútua.
- P() // ou wait() → decrementa o valor do semáforo → pode bloquear.
- V() // ou signal() → incrementa o valor → pode desbloquear um processo.
- Semáforos podem ser binários (0 ou 1) ou contadores (inteiros positivos).
🔐 5. Seção Crítica
Trecho do código que acessa um recurso compartilhado. Apenas um processo ou thread deve executá-lo por vez → garante consistência.
Requisitos para evitar falhas:
- Exclusão mútua → só um por vez.
- Progresso → ninguém fica travado sem necessidade.
- Espera limitada → nenhum processo espera para sempre.
🛑 6. Starvation
Quando um processo ou thread fica esperando indefinidamente por um recurso que nunca é liberado para ele → geralmente por ter prioridade baixa.
Aging → técnica que aumenta a prioridade com o tempo de espera, evitando inanição.
🔁 7. Escalonamento
- FIFO (First In, First Out) → ordem de chegada.
- SJF (Shortest Job First) → processo com menor tempo de CPU vai primeiro.
- Round Robin → revezamento por quantum de tempo.
- Prioridade → processos com maior prioridade executam antes.
- Aging → aumenta prioridade de processos que estão esperando há muito tempo.
⏱️ 8. Cálculo de Tempos
- Tempo de Espera → tempo que o processo passa aguardando na fila: início da execução - chegada
- Tempo de Retorno → tempo total que o processo leva desde que chegou até ser concluído: término - chegada
📉 9. Ordem de Execução
A escolha da ordem de execução dos processos afeta diretamente o tempo médio de espera. Executar primeiro os processos com menor tempo de CPU tende a reduzir esse tempo → estratégia baseada no algoritmo SJF.
O tempo médio de resposta melhora com uma fila organizada de forma eficiente.
🍴 10. Fork()
A chamada fork() cria um novo processo (cópia do processo pai).
Cada fork() duplica os processos existentes. No exemplo acima, serão criados 4 processos:
- 1 processo original (pai)
- 1º fork → 2 processos
- 2º fork → cada um dos 2 anteriores cria mais 1 → total = 4 processos
Organização: pai → dois filhos → cada filho cria um neto.