5Surveillance avancée des processus
Utilisez htop ou top pour identifier le processus qui consomme le plus de CPU.
Avec la commande top, les processus sont triés par défaut par utilisation CPU décroissante.
Exemple de réponse :
- Processus : python3 ou python
- PID : 1234 (variable selon le systĂšme)
- %CPU : 25.3% (variable selon la charge)
- Le serveur X11 (interface graphique)
- Les navigateurs web (Chromium)
- Les processus Python en cours d'exécution
Quelle commande permet de trier les processus par utilisation mémoire avec ps ?
Commande principale :
$ ps aux --sort=-%mem
Pour afficher seulement les 10 premiers :
$ ps aux --sort=-%mem | head -11
Explications :
aux: affiche tous les processus avec détails--sort=-%mem: trie par mémoire décroissante (le-indique l'ordre décroissant)- On peut aussi utiliser
--sort=%mempour un tri croissant
Alternative avec sélection des colonnes :
$ ps -eo pid,user,%mem,%cpu,cmd --sort=-%mem | head -10
Combien de processus Python sont actuellement en cours d'exécution ?
Commande pour compter :
$ pgrep python | wc -l
Pour voir les détails :
$ pgrep -a python
Exemple de réponse : 5 processus Python (si on a lancé 5 instances d'infini.py)
- Plus efficace que
ps aux | grep python - Ne capture pas le processus grep lui-mĂȘme
- Options avancées :
-upour filtrer par utilisateur,-lpour afficher les noms
Pour tuer tous les processus Python d'un coup :
$ pkill python
6Signaux et communication entre processus
Combien de signaux différents existe-t-il ? Notez les numéros et noms des signaux.
Il existe 64 signaux sous Linux (numérotés de 1 à 64).
Commande pour voir tous les signaux :
$ kill -l
Principaux signaux :
| Signal | Numéro | Nom | Description |
|---|---|---|---|
| Terminer proprement | 15 | SIGTERM | Demande au processus de se terminer proprement (peut ĂȘtre interceptĂ©) |
| Forcer l'arrĂȘt | 9 | SIGKILL | Force l'arrĂȘt immĂ©diat (ne peut PAS ĂȘtre interceptĂ©) |
| Suspendre | 19 | SIGSTOP | Suspend le processus (ne peut PAS ĂȘtre interceptĂ©) |
Autres signaux importants :
- Signal 1 (SIGHUP) : Rechargement de la configuration (pour les démons)
- Signal 2 (SIGINT) : Interruption (équivalent à Ctrl+C)
- Signal 18 (SIGCONT) : Reprend un processus suspendu
- Signal 20 (SIGTSTP) : Suspend (équivalent à Ctrl+Z)
Quel est l'état du processus (colonne STAT) lorsqu'il est suspendu ?
Commandes à exécuter :
# Lancer infini.py
$ python infini.py &
[1] 5432
# Suspendre le processus
$ kill -STOP 5432
# Vérifier l'état
$ ps -o pid,stat,cmd -p 5432
Résultat attendu :
PID STAT CMD
5432 T python infini.py
Pour reprendre le processus :
$ kill -CONT 5432
# L'état redevient S (Sleeping) ou R (Running)
Ătats possibles (rappel) :
- R : Running (en cours d'exécution)
- S : Sleeping (en attente)
- T : sTopped (suspendu)
- Z : Zombie (terminé mais non récupéré par le parent)
- D : Uninterruptible sleep (attente I/O)
Quelle est la différence entre ces deux signaux ? Lequel devrait-on privilégier et pourquoi ?
| Aspect | SIGTERM (15) | SIGKILL (9) |
|---|---|---|
| Interception | â Peut ĂȘtre interceptĂ© | â NE peut PAS ĂȘtre interceptĂ© |
| Nettoyage | â Permet la terminaison propre | â ArrĂȘt brutal, pas de nettoyage |
| Commande | kill PID ou kill -15 PID |
kill -9 PID |
| Usage | đ„ Ă privilĂ©gier en premier | â ïž En dernier recours |
- Envoie une "demande polie" de terminaison
- Le processus peut intercepter le signal et exécuter du code de nettoyage
- Permet de fermer proprement les fichiers, connexions réseau, libérer les ressources
- Force l'arrĂȘt immĂ©diat par le noyau
- Le processus ne peut PAS l'intercepter ni l'ignorer
- Pas de nettoyage possible â risque de corruption de donnĂ©es
- Peut laisser des ressources non libérées
Bonne pratique :
# 1. Essayer d'abord SIGTERM
$ kill 1234
# 2. Attendre quelques secondes (ex: 5-10s)
$ sleep 5
# 3. Si le processus ne s'est pas terminé, utiliser SIGKILL
$ kill -9 1234
7Processus zombies et orphelins
Créer un fichier zombie.py et détecter les processus zombies.
import os
import time
def main():
pid = os.fork()
if pid > 0:
# Processus parent
print(f"Parent (PID: {os.getpid()}) a créé l'enfant (PID: {pid})")
time.sleep(60) # Le parent attend sans récupérer l'enfant
else:
# Processus enfant
print(f"Enfant (PID: {os.getpid()}) se termine")
exit(0)
main()
Exécution et détection :
# Lancer le programme
$ python zombie.py
# Dans un autre terminal, détecter les zombies
$ ps aux | grep defunct
# ou
$ ps aux | grep Z
# ou plus précis
$ ps -eo pid,stat,cmd | grep Z
Résultat attendu :
1234 Z [python] <defunct>
Un processus zombie (ou defunct) est un processus qui a terminé son exécution mais dont l'entrée dans la table des processus n'a pas encore été supprimée par son processus parent.
Pourquoi existe-t-il ?
1. Cycle de vie normal d'un processus :
- Un processus enfant se termine (
exit()) - Le noyau conserve certaines informations (code de sortie, statistiques d'utilisation)
- Ces informations doivent ĂȘtre lues par le parent via
wait()ouwaitpid() - Une fois lues, le processus est complÚtement supprimé
2. Cas du zombie :
- L'enfant se termine
- Le parent ne récupÚre pas le code de sortie (n'appelle pas
wait()) - L'enfant reste en état zombie en attendant que le parent le récupÚre
3. Caractéristiques d'un zombie :
- N'utilise aucune ressource CPU ou mémoire (sauf l'entrée dans la table)
- Ătat : Z (Zombie) ou <defunct>
- Ne peut pas ĂȘtre tuĂ© avec
kill(il est déjà mort !) - Disparaßt quand le parent appelle
wait()ou se termine
Méthodes pour éliminer un zombie :
1. Solution propre : Le parent récupÚre l'enfant
Modifier le code pour que le parent appelle wait() :
import os
import sys
def main():
pid = os.fork()
if pid > 0:
# Processus parent
print(f"Parent (PID: {os.getpid()}) a créé l'enfant (PID: {pid})")
# Attendre que l'enfant se termine et récupérer son état
child_pid, status = os.wait()
print(f"Enfant {child_pid} terminé avec le code {status}")
else:
# Processus enfant
print(f"Enfant (PID: {os.getpid()}) se termine")
sys.exit(0)
main()
2. Tuer le processus parent
# Trouver le PID du parent
$ ps -eo pid,ppid,stat,cmd | grep defunct
# Tuer le parent
$ kill PPID_du_parent
3. On ne peut PAS tuer directement un zombie
$ kill -9 PID_zombie # â Inefficace (dĂ©jĂ mort)
$ kill -15 PID_zombie # â Inefficace
| Méthode | Commande/Action | Efficacité |
|---|---|---|
| Récupération par le parent | os.wait() dans le code |
â Solution idĂ©ale |
| Gestionnaire SIGCHLD | signal.signal(SIGCHLD, handler) |
â Solution professionnelle |
| Tuer le parent | kill PPID |
â ïž Fonctionne mais brutal |
| Tuer le zombie | kill -9 PID_zombie |
â Impossible |
8Priorités et ordonnancement
Lancez deux instances de infini.py avec des priorités différentes et observez les valeurs NI.
Commandes à exécuter :
# Instance avec priorité basse (moins prioritaire)
$ nice -n 10 python infini.py &
[1] 2345
# Instance avec priorité haute (plus prioritaire - nécessite sudo)
$ sudo nice -n -5 python infini.py &
[2] 2346
# Afficher les priorités
$ ps -l
- Valeurs de -20 Ă 19
- -20 = priorité maximale (processus trÚs prioritaire)
- 0 = priorité par défaut
- 19 = priorité minimale (processus "trÚs gentil")
- Seul root peut définir des valeurs négatives (priorité haute)
Résultat attendu avec ps -l :
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
0 S 1000 2345 1234 0 90 10 - 123 - pts/0 0:00 python infini.py
0 S 1000 2346 1234 0 75 -5 - 123 - pts/0 0:00 python infini.py
- Processus 2345 : NI = 10 (priorité basse, PRI = 90)
- Processus 2346 : NI = -5 (priorité haute, PRI = 75)
Plus la valeur PRI est basse, plus le processus est prioritaire.
PRI = 80 + NI (approximativement)
Le noyau calcule la priorité effective (PRI) en fonction de la valeur nice (NI) et d'autres facteurs.
Quelle commande permet de réduire la priorité d'un processus en cours ?
Commande renice :
# Rendre un processus "plus gentil" (réduire sa priorité)
$ renice +10 -p 2345
# Augmenter la priorité (nécessite sudo)
$ sudo renice -10 -p 2346
Syntaxe générale :
renice [nouvelle_valeur_nice] -p [PID]
renice [nouvelle_valeur_nice] -u [utilisateur]
renice [nouvelle_valeur_nice] -g [groupe]
Exemples pratiques :
# Réduire la priorité de tous les processus d'un utilisateur
$ sudo renice +15 -u nomeleve
# Vérifier le changement
$ ps -l -u nomeleve
- Un utilisateur normal ne peut qu'augmenter sa valeur nice (réduire sa priorité)
- Seul root peut diminuer la valeur nice (augmenter la priorité)
- On ne peut pas revenir Ă une valeur plus basse sans droits root
Cas d'usage réels :
- Compilation :
nice -n 15 make(ne pas ralentir le systĂšme) - Sauvegarde :
nice -n 10 rsync ...(basse priorité) - Serveur critique :
sudo renice -10 -p PID_serveur(haute priorité)
9Processus démon
Qu'est-ce qui caractérise un processus démon dans la colonne TTY ?
Commande pour lister les démons :
$ ps aux | grep -E '^\w+\s+\d+.*\?'
# ou plus simple
$ ps aux | grep ' ?'
Signification :
- Le ? indique que le processus n'est pas attaché à un terminal
- Les démons tournent en arriÚre-plan sans interaction utilisateur
- Ils démarrent généralement au boot du systÚme
- Exemples : serveurs web, bases de données, services systÚme
Exemple de sortie :
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.1 0.4 168844 9256 ? Ss 08:15 0:02 /sbin/init
root 385 0.0 0.2 29008 5284 ? Ss 08:15 0:00 /lib/systemd/systemd-journald
root 425 0.0 0.1 20644 3156 ? Ss 08:15 0:00 /lib/systemd/systemd-udevd
message+ 632 0.0 0.1 7352 3524 ? Ss 08:15 0:00 /usr/bin/dbus-daemon
- pts/0, pts/1, tty1 : Processus attachés à un terminal (interactifs)
- ? : Processus démons (non interactifs)
Citez 3 services actifs et expliquez leur rĂŽle.
Commande pour lister les services :
$ systemctl list-units --type=service --state=active
Pour voir les détails d'un service :
$ systemctl status nom_service
Exemples de services courants :
1. ssh.service (sshd)
$ systemctl status ssh
RÎle : Serveur SSH (Secure Shell) qui permet les connexions à distance sécurisées au Raspberry Pi. C'est grùce à ce service que vous pouvez vous connecter avec ssh depuis un autre ordinateur.
- Port par défaut : 22
- Configuration : /etc/ssh/sshd_config
- Essentiel pour l'administration Ă distance
2. systemd-journald.service
$ systemctl status systemd-journald
RÎle : Service de journalisation systÚme qui collecte et stocke les logs de tous les services et du noyau. Il permet de consulter l'historique des événements systÚme.
- Commande pour voir les logs :
journalctl - Logs stockés en binaire (plus efficace)
- Permet le dépannage et le diagnostic
3. cron.service
$ systemctl status cron
RÎle : Planificateur de tùches qui exécute des commandes ou scripts à des moments programmés (toutes les heures, tous les jours, etc.).
- Configuration :
crontab -e - Utilisé pour les sauvegardes automatiques, mises à jour, etc.
- Format : minute heure jour mois jour_semaine commande
Autres services importants :
- networking.service : Gestion des interfaces réseau
- systemd-timesyncd.service : Synchronisation de l'heure via NTP
- bluetooth.service : Gestion du Bluetooth
- avahi-daemon.service : Découverte de services réseau (mDNS)
- dbus.service : Bus de messages inter-processus
Commandes utiles pour gérer les services :
# Démarrer un service
$ sudo systemctl start nom_service
# ArrĂȘter un service
$ sudo systemctl stop nom_service
# Redémarrer un service
$ sudo systemctl restart nom_service
# Activer au démarrage
$ sudo systemctl enable nom_service
# Désactiver au démarrage
$ sudo systemctl disable nom_service
# Vérifier si un service est actif
$ systemctl is-active nom_service
# Voir les logs d'un service
$ journalctl -u nom_service -f
Tous les démons sont généralement des enfants (directs ou indirects) du processus systemd (PID 1) sur les systÚmes modernes, ou init sur les anciens systÚmes.