IFCE Horizonte · Portal
ADS23 · Sistemas Operacionais

Mão na massa · ~41 min

CPU-bound × I/O-bound na prática — e o consumo de um container ao vivo

Hoje você provoca, de propósito, um processo CPU-bound e um I/O-bound pra ver a diferença no top, separa stdout de stderr, encadeia processos com pipes, e fecha com o reforço Docker: acompanhar o consumo de um container em tempo real.

Passos 1–4 · CPU-bound, I/O-bound, stderr e pipesPassos 5–6 · Reforço Docker: docker stats

📋 Hoje começa a N1 da 1ª etapa — o Raio-X

Além da prática, hoje as equipes do relatório Raio-X se formam: duplas ou trios.

  • Leia o enunciado do Raio-X. Os laboratórios dos Encontros 1 a 7 são as seções do relatório.
  • A entrega parcial (seções 1 a 4) é a N1. Ela é enviada em PDF pelo portal, até a sexta-feira seguinte, às 23:59.
  • Confira se os quizzes dos encontros anteriores foram enviados: o portfólio vale 20% da nota da etapa.

Passo 1 de 6

Provocando um processo CPU-bound

Vamos criar, de propósito, um processo que só calcula sem parar — sem nunca esperar por disco ou rede.
1yes > /dev/null & depois top

O que é

yes imprime "y" infinitamente. O > /dev/null descarta a saída (senão lotaria a tela), e o & manda rodar em segundo plano.

Por que importa

É o exemplo mais simples de processo CPU-bound: nunca bloqueia esperando E/S, só usa CPU sem parar.

$ yes > /dev/null &
[1] 5231
$ top
%Cpu(s): 50.2 us,  0.3 sy,  0.0 ni, 49.5 id,  0.0 wa
PID  USER  S  %CPU  %MEM COMMAND
5231  aluno R  99.3   0.0  yes
O que esperar:

na lista, o yes aparece perto de 100% de CPU, com estado R (rodando), sozinho no topo. Na linha %Cpu(s) lá em cima, porém, o total fica perto de 50%: a sua VM tem 2 núcleos, e o yes ocupa um só. Aperte 1 dentro do top para ver cada núcleo separado. Aperte q pra sair — o yes continua rodando em segundo plano.

Como eu paro o yes depois?

Rode kill %1 (usa o número de "job" que apareceu entre colchetes) ou descubra o PID com ps aux | grep yes e rode kill <PID>. Não esqueça — ele fica consumindo CPU até você matá-lo ou fechar o terminal.

Passo 2 de 6

Provocando um processo I/O-bound

Agora um processo que mexe bastante com disco, mas usa pouca CPU — a espera é do disco, não do processador.
2dd if=/dev/zero of=arquivo_grande bs=1M count=1000 oflag=direct

O que é

dd copia 1000 blocos de 1 MB cheios de zeros pra um arquivo novo — cria ~1 GB gravado em disco. O oflag=direct manda escrever direto no disco, sem passar pela memória antes.

Por que importa

Processo claramente I/O-bound: o gargalo é a velocidade do disco, não da CPU. O dd passa a maior parte do tempo bloqueado, esperando cada bloco ser gravado.

$ dd if=/dev/zero of=arquivo_grande bs=1M count=1000 oflag=direct
1000+0 registros de entrada
1000+0 registros de saída
1048576000 bytes (1,0 GB) copiados, 6,1 s, 172 MB/s
O que esperar:

abra um segundo terminal com top antes de rodar o dd. Enquanto ele grava, o dd aparece com CPU bem menor que a do yes, quase sempre com estado D (esperando o disco), e o valor de wa na linha %Cpu(s) sobe: é a CPU ociosa esperando E/S.

Por que o oflag=direct? E se eu tirar?

Sem ele, o Linux grava primeiro na RAM (o cache de páginas) e só depois descarrega no disco, em segundo plano. O dd termina rápido e aparece gastando CPU, porque o trabalho dele virou copiar memória. A espera pelo disco fica escondida num processo do kernel. Experimente sem o oflag=direct e compare: é um ótimo assunto para a observação livre.

Não deu tempo de ver o dd rodando no top

Normal em discos rápidos (SSD) — o dd pode terminar rápido demais. Aumente count=1000 pra count=3000 e tente de novo, observando o top em paralelo.

compare o que você viu no top entre o yes (passo 1) e o dd (passo 2). Qual consumiu mais CPU, e por quê?

0 / 40 caracteres

Passo 3 de 6

Separando saída normal de erro

Vamos provocar um erro de propósito e confirmar que stdout e stderr são, de fato, dois canais separados.
3ls arquivo_inexistente 2> erro.txt; cat erro.txt

O que é

2> redireciona só o canal 2 (stderr) pro arquivo erro.txt. A mensagem de erro do ls vai pro arquivo, não pra tela.

Por que importa

Prova, na prática, que stdout (1) e stderr (2) são canais independentes — por isso dá pra guardar só os erros de um comando sem perder a saída normal.

$ ls arquivo_inexistente 2> erro.txt; cat erro.txt
ls: não é possível acessar 'arquivo_inexistente': Arquivo ou diretório inexistente
O que esperar:

nada aparece na tela quando você roda o ls (o erro foi direto pro arquivo) — só o cat erro.txt seguinte mostra a mensagem.

Passo 4 de 6

Encadeando processos com pipes

Vamos contar quantos processos existem, e depois filtrar antes de contar — dois pipelines curtos.
4ps aux | wc -l e ps aux | grep bash | wc -l

O que é

wc -l conta linhas. O primeiro pipe conta todos os processos; o segundo filtra só os que têm "bash" antes de contar.

Por que importa

Mostra um pipeline de três processos encadeados de uma vez — exatamente o que o slide de hoje explicou por dentro.

$ ps aux | wc -l
87
$ ps aux | grep bash | wc -l
2
O que esperar:

o primeiro número deve ser bem maior que o segundo. O "2" do segundo comando inclui o seu terminal bash e o próprio processo grep bash que acabou de rodar (o mesmo efeito visto no Encontro 5).

Reforço Docker · docker stats

Passo 5 de 6

Vendo o consumo de um container ao vivo

Depois de tanto observar processos comuns, vamos ver o mesmo tipo de informação, só que organizada por container.
5docker run -d --name statsdemo alpine sleep 300 depois docker stats --no-stream

O que é

Sobe um container ocioso (só sleep), e docker stats --no-stream tira uma "fotografia" única do consumo de todos os containers rodando.

Por que importa

É o top/ps do mundo Docker — mas organizado por container, não por processo do sistema inteiro.

$ docker run -d --name statsdemo alpine sleep 300
a13f0e9c7d21...
$ docker stats --no-stream
NAME       CPU %   MEM USAGE / LIMIT   NET I/O
statsdemo  0.00%   1.2MiB / 3.8GiB    906B / 0B
O que esperar:

o statsdemo deve aparecer com CPU próxima de 0% — ele só está dormindo (sleep), sem nenhum trabalho de verdade pra fazer.

Quero comparar com um container "ocupado"

Se sobrar tempo, tente docker run -d --name cpudemo alpine sh -c "yes > /dev/null" e rode docker stats --no-stream de novo — agora deve aparecer um container consumindo bem mais CPU, do mesmo jeito que o yes do passo 1.

o que o docker stats mostrou sobre o statsdemo? Compare com o que você esperava de um processo I/O-bound quase parado.

0 / 40 caracteres

Passo 6 de 6

Encerrando e limpando

Antes de fechar, pare e remova o container criado neste roteiro, apague o arquivo de 1 GB do passo 2 e encerre o yes do passo 1, se ainda estiver rodando.
6docker stop statsdemo && docker rm statsdemo && rm arquivo_grande erro.txt

O que é

docker stop encerra o container, docker rm remove o registro dele. Confira também se o yes do passo 1 já foi encerrado.

Por que importa

Boa prática básica: não deixar processos, containers ou arquivos de teste "esquecidos" consumindo recursos depois da aula. O arquivo_grande sozinho ocupa 1 GB do disco de 25 GB da VM.

O que esperar:

o nome statsdemo impresso duas vezes, confirmando parada e remoção. Rode ps aux | grep yes pra garantir que nenhum yes ficou pra trás.

livre: algo que te surpreendeu ou uma dúvida que sobrou de hoje

0 / 40 caracteres

Exemplo de observação forte × fraca

Observação fraca

"O yes usou mais CPU que o dd."

Observação forte

"O yes ficou perto de 100% de CPU, em estado R, porque é puramente CPU-bound — só calcula e imprime, sem nunca parar pra esperar nada. Já o dd com oflag=direct, mesmo movendo 1 GB pro disco, ficou com CPU baixa e em estado D, enquanto o wa subia: o gargalo real era a velocidade de escrita do disco, não o processamento."

Checklist final

  • Rodei o yes em segundo plano e vi ~100% de CPU no top
  • Rodei o dd e comparei o consumo de CPU com o yes
  • Separei stdout de stderr com 2>
  • Rodei os dois pipelines com ps aux | wc -l e | grep | wc -l
  • Subi um container e observei o consumo com docker stats --no-stream
  • Parei e removi o container, e matei qualquer yes esquecido
  • Preenchi as 3 observações acima (vou colar no quiz semanal)
  • Formei minha equipe do Raio-X e li o enunciado
0 / 8 verificados