Un processus est une instance d’un programme : le noyau lui donne un identifiant, un espace d’adressage, une table de fichiers ouverts, des signaux et des limites. Un thread est une unité d’exécution à l’intérieur de ce processus. Plusieurs threads d’un même processus partagent le même tas, les mêmes descripteurs, le même répertoire courant. Ils ont chacun leur pile et leurs registres.
La phrase qui structure la réponse : isoler deux traitements, c’est deux processus ; les faire travailler sur les mêmes données en mémoire, c’est des threads.
Il ne veut pas la définition du manuel. Il veut savoir si vous comprenez ce qui est isolé et ce qui ne l’est pas, parce que c’est ça qui décide du diagnostic.
Si un service Java consomme 8 Go et que ps montre un seul PID avec des dizaines de threads, tuer « un thread » n’existe pas comme opération propre. kill vise le processus. Tous les threads meurent ensemble. Inversement, un pipeline de deux commandes (grep | sort) est deux processus : l’un peut échouer sans que l’autre soit déjà mort, et ils ne voient pas les variables de l’autre.
Le partage mémoire a un coût. Un débordement de tampon, un pointeur fou, un deadlock : ça n’est pas confiné à un thread. Le processus entier devient incohérent. C’est la raison pour laquelle un navigateur met chaque onglet dans un processus séparé, et pourquoi beaucoup de serveurs préfèrent des workers (processus) à une forêt de threads quand l’isolation vaut plus que le coût de la copie.
ps -o pid,tid,psr,comm,state -L -p 1234-L affiche les threads. Le PID est le même ; le TID change. top -H fait la même chose en interactif. /proc/1234/status donne Threads: ; /proc/1234/task/ liste chaque thread.
Un processus a un PID unique dans son espace de noms. Les threads Linux sont des tâches du même groupe (tgid). C’est pour cela que ps aux sans -L vous montre une ligne par processus : le noyau agrège.
« Pourquoi ne pas tout mettre en threads, c’est plus léger ? »
Parce que la légèreté se paie en sûreté. Créer un processus coûte plus cher (copie de la table des pages, copy-on-write) et la communication passe par des tubes, des sockets, de la mémoire partagée explicite. En échange, un crash reste local, les permissions peuvent différer, et ulimit s’applique au processus. Les threads partagent aussi le même UID, les mêmes sockets : une fuite de descripteur ou un chdir surprise affecte tout le monde.
« Et dans un conteneur ? »
Le PID 1 du conteneur est un processus. Ses threads restent dans le même cgroup et le même namespace. Si le PID 1 meurt, le runtime arrête le conteneur. Confondre « beaucoup de threads » et « beaucoup de processus » mène à mal lire docker stats et à tuer le mauvais niveau.
En entretien, terminer par le critère de choix : isolation contre partage. Tout le reste — fork, pools, GIL Python, workers gunicorn — découle de cette ligne.