Pular para o conteúdo principal

Lab 4.2 - Controle de Processos

Objetivos​

Ao final deste lab, você será capaz de:

  • Iniciar processos
  • Parar processos (kill, killall, pkill)
  • Suspender e retomar processos
  • Gerenciar jobs em segundo plano
  • Compreender sinais do Linux

Pré-requisitos​

  • Ubuntu 24.04 instalado
  • Terminal aberto
  • Acesso de usuário comum

Exercício 1: Iniciar Processos​

Etapa 1: Processo em Primeiro Plano​

# Iniciar um processo simples
sleep 60

# Iniciar um processo interativo
nano test.txt
# (Ctrl+X para sair)

Etapa 2: Processo em Segundo Plano​

# Iniciar em segundo plano com &
sleep 300 &

# Ver o PID
echo $!

# Ver os jobs
jobs

# Ver os processos em segundo plano
ps aux | grep sleep

Etapa 3: nohup​

# Iniciar um processo que continua após logout
nohup sleep 600 > sleep.log 2>&1 &

# Verificar
ps aux | grep sleep
cat sleep.log

Exercício 2: Sinais do Linux​

Etapa 1: Compreender os Sinais​

# Ver todos os sinais
kill -l

# Sinais comuns:
# SIGTERM (15): Finalização graciosa
# SIGKILL (9): Finalização forçada (não pode ser ignorado)
# SIGSTOP (19): Suspender
# SIGCONT (18): Retomar
# SIGHUP (1): Hang up (reiniciar)

Etapa 2: Enviar Sinais​

# Iniciar um processo
sleep 300 &
PID=$!

# Enviar SIGTERM (finalização graciosa)
kill $PID

# Ou com o número
kill -15 $PID

# Verificar
ps -p $PID

Exercício 3: kill, killall, pkill​

Etapa 1: kill​

# Iniciar vários processos
sleep 100 &
PID1=$!
sleep 200 &
PID2=$!

# Matar um processo específico
kill $PID1

# Matar vários processos
kill $PID1 $PID2

# Matar com força (SIGKILL)
kill -9 $PID1

Etapa 2: killall​

# Iniciar várias instâncias
sleep 100 &
sleep 200 &
sleep 300 &

# Matar todos os processos "sleep"
killall sleep

# Com confirmação
killall -i sleep

# Verificar
ps aux | grep sleep

Etapa 3: pkill​

# Iniciar processos
sleep 100 &
sleep 200 &

# Matar por nome (padrão)
pkill sleep

# Matar por usuário
pkill -u $USER sleep

# Ver o que será morto (dry-run)
pkill -l sleep

Exercício 4: Suspender e Retomar​

Etapa 1: Suspender um Processo​

# Iniciar um processo
sleep 300 &

# Suspender com kill
kill -STOP $!

# Ou com Ctrl+Z (se em primeiro plano)
# sleep 300
# [Pressione Ctrl+Z]

# Ver o estado
ps aux | grep sleep
# Note o "T" (stopped)

Etapa 2: Retomar um Processo​

# Retomar em segundo plano
kill -CONT $PID

# Retomar em primeiro plano
fg

# Retomar em segundo plano
bg

Exercício 5: Gerenciamento de Jobs​

Etapa 1: Comandos de Jobs​

# Iniciar vários jobs
sleep 100 &
sleep 200 &
sleep 300 &

# Ver os jobs
jobs

# Ver com PID
jobs -l

# Trazer um job para o primeiro plano
fg %1 # Job número 1

# Colocar em segundo plano
bg %1

# Matar um job
kill %1

Etapa 2: Script com Jobs​

# Criar um script
cat > test-jobs.sh << 'EOF'
#!/bin/bash
sleep 10 &
JOB1=$!
sleep 20 &
JOB2=$!

echo "Jobs iniciados: $JOB1, $JOB2"
jobs

# Esperar terminar
wait $JOB1
echo "Job 1 finalizado"
wait $JOB2
echo "Job 2 finalizado"
EOF

chmod +x test-jobs.sh
./test-jobs.sh

Exercício 6: Processo Zumbi​

Etapa 1: Criar um Zumbi (para teste)​

# Script que cria um zumbi
cat > zombie.sh << 'EOF'
#!/bin/bash
# Fork em um processo filho que morre imediatamente
# O pai não faz wait()
(
sleep 1
exit
) &
# Pai não faz wait, filho vira zumbi
sleep 10
EOF

chmod +x zombie.sh
./zombie.sh &

# Ver os zumbis
ps aux | grep -w Z

Etapa 2: Limpar Zumbis​

# Zumbis são limpos automaticamente pelo init (PID 1)
# Mas pode forçar matando o pai
ps aux | grep zombie
# Encontrar o PID do pai e matá-lo

Exercício 7: Prática Completa​

Etapa 1: Cenário Real​

# Iniciar um servidor web de teste
python3 -m http.server 8000 &
SERVER_PID=$!

# Verificar se está rodando
ps -p $SERVER_PID
curl http://localhost:8000

# Parar graciosamente
kill $SERVER_PID

# Verificar
ps -p $SERVER_PID

Etapa 2: Script de Gerenciamento​

# Script para gerenciar um processo
cat > manage-process.sh << 'EOF'
#!/bin/bash
PROCESS="python3"
ACTION=$1

case $ACTION in
start)
python3 -m http.server 8000 > /dev/null 2>&1 &
echo "Servidor iniciado: $!"
;;
stop)
pkill -f "python3 -m http.server"
echo "Servidor parado"
;;
status)
if pgrep -f "python3 -m http.server" > /dev/null; then
echo "Servidor ativo"
ps aux | grep "python3 -m http.server" | grep -v grep
else
echo "Servidor inativo"
fi
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "Uso: $0 {start|stop|status|restart}"
exit 1
;;
esac
EOF

chmod +x manage-process.sh

# Usar
./manage-process.sh start
./manage-process.sh status
./manage-process.sh stop

Verificação​

Checklist​

Verifique se você consegue:

  • Iniciar processos (primeiro plano e segundo plano)
  • Enviar sinais (kill, killall, pkill)
  • Suspender e retomar processos
  • Gerenciar jobs (jobs, fg, bg)
  • Compreender os diferentes sinais
  • Gerenciar processos na prática

Perguntas para Reflexão​

  1. Qual a diferença entre SIGTERM e SIGKILL?

    • SIGTERM: Finalização graciosa (pode ser interceptado)
    • SIGKILL: Finalização forçada (não pode ser ignorado)
  2. Por que usar nohup?

    • Permite que o processo continue após logout do terminal
    • Útil para tarefas longas
  3. O que é um processo zumbi?

    • Processo finalizado cujo pai não fez wait()
    • Limpo automaticamente pelo init

Próximos Passos​

  • Lab 4.3: Prioridades e Nice Values
  • Lab 4.4: Jobs e Tarefas em Segundo Plano
  • Capítulo 4.2: Visualização de Processos

Lab criado em: Dezembro 2024 - Testado no Ubuntu 24.04