IFCE Horizonte · Portal
ADS23 · Sistemas Operacionais

Mão na massa · ~54 min

Vendo a condição de corrida acontecer — e ensaiando o container da N2

Hoje você roda um script simples que expõe o bug de concorrência na prática (o mesmo resultado variando a cada execução), identifica a região crítica no próprio código, e fecha com a sua equipe ensaiando o ciclo completo do container que será defendido na N2.

Passos 1–3 · Condição de corrida na práticaPassos 4–5 · Ensaio Docker da N2 (em equipe)

⏭️ Preparando o próximo marco — N2

A N2 da 1ª etapa acontece no Encontro 8: relatório "Raio-X" em dupla/trio, defesa de 5–6 minutos, e o container Raio-X da equipe rodando ao vivo durante a apresentação. Tudo está no enunciado.

Os passos 4 e 5 de hoje são justamente o ensaio desse momento — quanto mais suave ficar aqui, menos risco no dia que vale nota. A condição de corrida dos passos 1 a 3 é a seção 6 do relatório.

Passo 1 de 5

Criando o script que expõe a corrida

Vamos escrever um script pequeno que incrementa um "saldo" compartilhado, sem nenhuma proteção — o cenário perfeito pra condição de corrida aparecer.
1nano contador_concorrente.sh

O que é

Um script que sobe dois processos em segundo plano, cada um incrementando 500 vezes o mesmo arquivo saldo.txt — sem nenhuma trava entre leitura e escrita.

Por que importa

É a mesma lógica do Caixa A e Caixa B do slide de hoje, só que rodável de verdade na sua VM.

contador_concorrente.sh

#!/bin/bash
echo 0 > saldo.txt

incrementa() {
for i in $(seq 1 500); do
  valor=$(cat saldo.txt)
  valor=$((valor + 1))
  echo $valor > saldo.txt
done
}

incrementa &
incrementa &
wait

echo "Resultado esperado: 1000 | Resultado obtido: $(cat saldo.txt)"
O que esperar:

cole esse conteúdo no nano, salve (Ctrl+O, Enter, Ctrl+X) e rode chmod +x contador_concorrente.sh antes do próximo passo. Repare nas três linhas dentro do for — valor=$(cat saldo.txt), valor=$((valor + 1)) e echo $valor > saldo.txt: elas são a região crítica, e voltam no passo 3.

Não tenho o nano instalado, e agora?

Use cat > contador_concorrente.sh, cole o conteúdo, e finalize com Ctrl+D. Depois rode chmod +x contador_concorrente.sh normalmente.

Passo 2 de 5

Rodando várias vezes e comparando resultados

Se o script fosse "seguro" contra concorrência, o resultado seria sempre 1000. Vamos ver se é isso que acontece.
2./contador_concorrente.sh (repita 4–5 vezes)

O que é

Cada execução sobe os dois "incrementadores" concorrentes de novo, do zero.

Por que importa

Rodar só uma vez pode até dar 1000 por sorte — repetir é o que revela a inconsistência.

$ ./contador_concorrente.sh
Resultado esperado: 1000 | Resultado obtido: 742
$ ./contador_concorrente.sh
Resultado esperado: 1000 | Resultado obtido: 311
$ ./contador_concorrente.sh
Resultado esperado: 1000 | Resultado obtido: 861
O que esperar:

resultados diferentes a cada execução, quase sempre abaixo de 1000 — algumas atualizações foram "perdidas" porque os dois processos leram o mesmo valor antigo de saldo.txt antes de qualquer um gravar de volta. Os seus números não vão bater com os do exemplo, e isso é justamente o ponto.

Deu um número muito baixo, tipo 40. O script quebrou?

Não: é uma segunda corrida escondida na mesma região crítica. O > do echo $valor > saldo.txt esvazia o arquivo antes de escrever o número. Se o outro processo faz o cat exatamente nesse instante, lê um arquivo vazio; o bash trata vazio como zero, e o saldo volta para 1. É o mesmo bug, com um estrago maior.

Meu resultado deu sempre 1000, não vejo o bug

Acontece em máquinas muito rápidas — os dois processos raramente se cruzam no tempo certo. Tente aumentar o seq 1 500 pra seq 1 3000 no script e rode de novo.

quais resultados você obteve nas suas execuções? Por que o número final varia mesmo rodando exatamente o mesmo script?

0 / 40 caracteres

Passo 3 de 5

Encontrando a região crítica no próprio código

Sem rodar nada novo — releia o script do passo 1 e aponte exatamente onde mora o perigo.
3Releitura do script — sem comando novo

O que é

As três linhas dentro do for no passo 1: ler o saldo (cat), calcular o novo valor ($((valor + 1))), gravar de volta (echo ... >).

Por que importa

É exatamente a região crítica do slide de hoje — o trecho que precisaria de exclusão mútua pra ficar seguro.

O que esperar:

perceba que, entre o cat saldo.txt e o echo $valor > saldo.txt, o outro processo tem tempo de sobra pra ler o mesmo valor "desatualizado" — é exatamente a brecha da condição de corrida.

se você tivesse que corrigir o script pra sempre dar 1000, o que impediria os dois processos de ler o saldo ao mesmo tempo?

0 / 40 caracteres

Ensaio Docker · N2 (em equipe)

Passo 4 de 5

Primeiro ensaio: build → run → demonstração → stop

Reúna-se com sua dupla/trio do Raio-X. Usando o Dockerfile e o raio-x.sh do enunciado, cronometre o ciclo completo do zero.
4docker build -t raio-x-equipe . → docker run --rm raio-x-equipe → sh raio-x.sh (na VM) → explicar as diferenças

O que é

O mesmo ciclo que vocês vão executar ao vivo durante a defesa da N2 — construir a imagem, rodar o container, e comparar o raio-x visto de dentro com o visto da VM. O --rm apaga o container assim que ele termina.

Por que importa

Erros de ambiente (porta ocupada, dependência esquecida, Dockerfile desatualizado) aparecem agora — não durante a apresentação que vale nota.

O que esperar:

anote o tempo total do ciclo e qualquer erro encontrado. É normal a primeira tentativa não sair perfeita — é exatamente pra isso que o ensaio existe.

Nossa equipe ainda não montou o container

Comece pelo ponto de partida mínimo do enunciado: são dois arquivos curtos, os mesmos do Encontro 4 com outro script. Ensaiar com a versão mínima já revela problemas de ambiente cedo; a equipe aprimora depois.

Passo 5 de 5

Segundo ensaio: mais rápido e sem erros

Repitam o ciclo do passo 4 uma segunda vez, tentando corrigir qualquer problema encontrado e reduzir o tempo total.
5Repetir o ciclo completo do passo 4

O que é

A mesma sequência — build, run, demonstração, stop/rm — cronometrada de novo.

Por que importa

A defesa real tem um timebox curto (5–6 minutos) — chegar treinado reduz a chance de travar durante a nota.

O que esperar:

o segundo ciclo deve ser mais rápido e sem os erros da primeira tentativa. Se algo ainda travar, anote — é informação valiosa pra resolver antes do Encontro 8.

livre: como foi o ensaio do container da sua equipe? Algo travou, ou uma dúvida que sobrou de hoje

0 / 40 caracteres

Exemplo de observação forte × fraca

Observação fraca

"O resultado do script deu diferente toda vez."

Observação forte

"Rodei 4 vezes e obtive 742, 1000, 861 e 903. A variação acontece porque, entre o momento em que um processo lê o saldo e grava o novo valor, o outro processo pode ler exatamente o mesmo valor antigo — perdendo o incremento de quem gravou primeiro. É a região crítica do script sem nenhuma proteção de exclusão mútua."

Checklist final

  • Criei e testei o contador_concorrente.sh
  • Rodei o script pelo menos 4 vezes e vi resultados diferentes
  • Identifiquei as linhas exatas da região crítica no script
  • Fiz o primeiro ensaio completo do container da N2 com minha equipe
  • Repeti o ensaio, mais rápido e sem os erros da primeira vez
  • Preenchi as 3 observações acima (vou colar no quiz semanal)
0 / 6 verificados