Cheat sheet
Fórmulas, condições, chamadas POSIX e erros a verificar antes de responder.
Processos
| Chamada | Retorno | Verificação |
|---|---|---|
fork | -1, 0 ou PID do filho | Trata a falha; no filho e no pai segue ramos separados |
execvp | Só retorna em falha | Mantém o PID; vetor termina em NULL |
waitpid | PID ou -1 | Repete em EINTR; interpreta com WIFEXITED antes de WEXITSTATUS |
exit / _exit | Não retorna | No filho após exec falhado usa _exit; exit repete limpezas herdadas |
- Um processo terminado liberta a memória de execução, mas resta uma entrada na tabela do núcleo com PID e estado até ser recolhido. Esse zombie já não executa.
- Um filho vivo cujo pai terminou é órfão; em Linux pode ser adotado por init ou por um subreaper.
- Dados privados ficam logicamente separados após
fork(COW); descritores herdados partilham a posição. - Contagem: se todos os processos chegam a cada
fork, forks dão processos. Filhos que terminam antes quebram a progressão. - Antes de
fork, descarrega buffers comfflushpara não duplicar saída. - Processos.
Escalonamento
- Hipóteses base dos exemplos: 1 CPU, uma rajada por processo, sem I/O e sem custo de troca.
- Com chegada , rajada , primeiro início e fim :
- Retorno .
- Espera (subtrai também o tempo bloqueado se houver I/O).
- Resposta .
- Utilização mede fração de CPU ocupada; débito conta tarefas por unidade de tempo.
| Política | Regra de escolha | Risco a verificar |
|---|---|---|
| FCFS | Ordem de chegada | Efeito de comboio com rajada longa à frente |
| SJF não preemptivo | Menor rajada entre as já prontas | Não adivinha chegadas futuras |
| SRTF | Menor tempo restante; reavalia em cada chegada | Inanição sem aging |
| RR com quantum | Fatia até ; quem não termina volta ao fim | Espera inclui intervalos entre fatias |
| Prioridades | Ordem definida | Inanição; usa aging ou quotas |
- Previsão da próxima rajada, com medida , previsão anterior e :
- Fração útil com fatias de duração e custo de troca , supondo fatias cheias e fila sempre ocupada: .
- CFS escolhe menor vruntime; peso maior faz o vruntime crescer mais devagar. Em
nice, valor menor significa maior prioridade. - Modelo de tempo real: 1 CPU, tarefas independentes e preemptivas, deadline igual ao período. Para a tarefa , é o custo máximo e o período; .
- RMS dá prioridade ao menor período; para tarefas é suficiente, não necessária.
- EDF escolhe a deadline absoluta mais próxima; decide.
- Métricas · Tempo real.
Memória e paginação
- Página e moldura com bytes. Para o virtual , com página , deslocamento , moldura e físico :
- O deslocamento passa intacto para o endereço físico.
- Tabela linear: com bits de endereço virtual e , há entradas. Exemplo de 32 bits com 4 KiB e 4 bytes por entrada: entradas, 4 MiB.
- Multinível com 10+10+12 bits: cria tabelas interiores só para regiões mapeadas.
- TLB guarda traduções; cache guarda conteúdo. Falta no TLB não é falta de página.
- Tempo efetivo com tabela de um nível, sem caches nem faltas. Aqui é o acesso ao TLB, o acesso à memória e a taxa de acerto, com :
- Acerto: .
- Falta: .
- Média: .
- Com duas tabelas no miss: .
- Custo com faltas de página. Aqui é o acesso normal, o serviço completo de falta incluindo a repetição, e a probabilidade de falta, todos na mesma unidade:
| Política | Vítima | Nota |
|---|---|---|
| FIFO | Entrada mais antiga | Acerto não reordena |
| LRU | Acesso menos recente | Cada acerto atualiza a ordem |
| OPT | Uso futuro mais distante | Referência mínima com futuro conhecido |
| Relógio | Primeiro bit 0 a partir da ponteira | Bit 1 é limpo e a ponteira avança |
| NRU | Primeira classe (R,M) não vazia | é referência desde a limpeza, é modificação |
- Fragmentação externa: falta de região contígua livre. Fragmentação interna: capacidade atribuída sem uso.
- FIFO pode dar mais faltas com mais molduras (anomalia de Belady). LRU e OPT são de pilha no modelo.
- Working set: páginas distintas nas últimas referências.
- Thrashing: paginação contínua sem trabalho útil. CPU pouco ocupada não pede mais processos; confirma a frequência de faltas.
- Tradução · Substituição.
Concorrência
- Protege a operação indivisível com mutex. A granularidade segue os dados, não o menor número de linhas.
- Semáforo conta permissões (
vazios=N,cheios=0) ou impõe ordem. Procedimento na fila limitada:- Espera por disponibilidade antes de obter o mutex.
- Obtém o mutex e atualiza índices.
- Liberta o mutex e anuncia depois.
pthread_cond_waitliberta o mutex e dorme de forma atómica; ao voltar, reobtém o mutex.- Passos do consumidor:
- Testa o predicado com o mutex obtido.
- Espera em
while, porque há despertares espúrios e outro consumidor pode levar o item. - Retira e sinaliza segundo o número de consumidores.
- O sinal permite sair da espera; não reserva um item nem entrega o mutex.
- Acessos concorrentes incompatíveis sem sincronização são data race, com comportamento indefinido em C.
volatilenão cria sincronização. - Impasse exige as quatro condições em simultâneo: exclusão mútua, retenção com espera, ausência de preempção e espera circular. Ordem global de locks quebra o ciclo.
- Banqueiro, com
Need=Max-AllocationeWork=Available:- Escolhe por concluir um processo com
Need<=Workem cada componente. - Soma
Work+=Allocationdesse processo. - Repete até incluir todos. Só concede o que mantém segurança.
- Escolhe por concluir um processo com
- Condição · Impasses.
Comunicação entre processos
- Pipe:
fd[0]lê,fd[1]escreve. Cria antes defork; depois defork, cada processo fecha as pontas que não usa. - EOF no pipe exige buffer vazio e todas as pontas de escrita fechadas. Passos:
- Leitor fecha a escrita herdada.
- Escritor fecha a escrita quando terminam os dados.
- Leitor esgota o buffer e recebe
0.
- Sem leitores, escrever pode gerar
SIGPIPEe falhar comEPIPEse o sinal não terminar o processo. dup2preparastdin/stdoutantes deexec. O supervisor fecha ambas as pontas e recolhe os filhos.- Fluxos não preservam fronteiras de mensagem: usa ciclos e define linhas, tamanho ou comprimento. Escritas curtas não provam EOF.
- Meio-fecho em sockets:
shutdown(fd, SHUT_WR)termina o pedido sem fechar a leitura da resposta. Em pipes, o fim usa fecho da escrita, nãoshutdown. - Sinais:
SIGKILLeSIGSTOPnão se capturam nem se ignoram. Usa nomes, não números.- No tratador, usa só funções async-signal-safe. Assinala com
volatile sig_atomic_te trabalha no fluxo normal. - Sinais padrão repetidos enquanto pendentes podem fundir-se; não os uses como contador. Sinais de tempo real têm fila.
- Contra a janela teste/dormir: bloqueia, instala com
sigaction, testa sob bloqueio e dorme comsigsuspend.
- Memória partilhada:
mmapfalha comMAP_FAILED.MAP_SHAREDpartilha;MAP_PRIVATEisola com COW.munmapremove; fechar o descritor não remove. Pai que lê depois dewaitpidestá ordenado; filas vivas exigem sincronização entre processos. - IPC.
C e ficheiros
- Argumentos:
argcinclui o nome do programa. Confirmaargcantes de lerargv[1].- Valida inteiros com
strtol: põeerrno=0, rejeitaERANGE, rejeita sem dígitos (fim==argv[1]) e rejeita resto (*fim!='\0'). Paraint, confirma tambémINT_MIN<=n<=INT_MAX. - Para o máximo de números que podem ser negativos, inicializa com o primeiro valor validado, não com zero.
- Strings:
strcpy(dst, src)exigestrlen(src)+1bytes no destino.strcat(dst, src)exigestrlen(dst)+strlen(src)+1bytes, comdstjá terminada.- As regiões não se podem sobrepor.
strlennão mede capacidade.
- Tempo de vida:
- Testa
NULLapós reserva.mallocnão inicializa;calloczera. - Em
realloc, usa temporário. Com tamanho maior que zero, a falha conserva o bloco antigo;realloc(p, 0)varia por implementação. - Após
free, o bloco deixa de ser válido; pôr um alias aNULLnão salva os outros.
- Testa
- Transferências:
openfalha com-1; descritor0é válido.fopenfalha comNULL.readdevolve>0bytes,0no fim e-1em erro.writepode entregar menos bytes: repete combuf+feitoen-feito, trataEINTRe não confunde erro com tamanho sem sinal.- Para copiar sem truncar primeiro: abre sem truncar, compara
st_dev/st_inoviafstate só depois trunca. - Cada
opentem posição própria;dupe herança deforkpartilham a descrição aberta. lseekdevolve a posição absoluta ou(off_t)-1. EOF é retorno0, não um byte.getlineinclui\nquando existe e pode pedir reserva; liberta o buffer no fim.
- Metadados:
- Lê
struct statsó após sucesso.statsegue links,lstatnão,fstatusa abertura. d_namenão é caminho: junta o diretório ou usafstatat. Repõeerrno=0antes de cadareaddir.- API.
- Lê
Sistema de ficheiros e I/O
- VFS fornece a interface comum e encaminha para cada implementação; não é um formato em disco.
- Inode guarda metadados e localização; diretório guarda nome para inode; descrição aberta guarda posição.
duppartilha posição; novaopenrecomeça.unlinkremove o nome sem invalidar aberturas.- Bitmap: um bit por bloco. Exemplo de 1 TiB em blocos de 4 KiB: blocos, bytes, 32 MiB.
- Índice com blocos de 4 KiB e apontadores de 4 bytes: 1024 entradas por bloco. Com 12 diretos, um simples e um duplo: diretos 0–11, simples 12–1035, duplo desde 1036.
- Durabilidade:
fflushentrega buffers ao sistema; não prova persistência.fsyncpede sincronização do ficheiro; confere erros de escrita, fecho e sincronização.- Criar ou renomear pode exigir sincronizar também o diretório.
- Disco HDD: posicionamento, rotação e transferência. A 7200 rpm, a espera média de rotação é 4,17 ms.
- Polling consulta estado em ciclo; interrupção anuncia o evento; DMA transfere com configuração e conclusão por interrupção.
- Shell:
- Expansão antes da execução; redirecionamentos não entram em
argv. > f 2>&1junta ambos emf;2>&1 > fdeixa stderr no destino antigo.uniqsó remove adjacentes;ls -lmostra modificação, não criação.
- Expansão antes da execução; redirecionamentos não entram em
- Implementação · I/O · Shell.