Threads und Prozesse sind Ausführungskontexte. Sie unterscheiden sich meist nur durch die Menge des gemeinsam genutzten Status (Speicher, Signalhandler, Dateideskriptoren, ...) mit den anderen Ausführungskontexten (Prozesse teilen sich wenig mit anderen Prozessen; Threads teilen sich viel mit den anderen Threads im selben Prozess).
Die meisten Betriebssysteme halten die beiden Dinge getrennt und kennen daher verschiedene Arten von Ausführungskontexten.
Der Linux-Kernel hingegen hat nur eine Art von Ausführungskontext, der in der Lage ist, Dinge mit anderen zu teilen oder nicht. Wenn Sie einen Prozess möchten, richten Sie ihn so ein, dass er wenig gemeinsam nutzt. Wenn Sie Threads möchten, richten Sie sie so ein, dass sie gemeinsam nutzen, was sie benötigen. Sie können die Dinge so einrichten, dass sie sich für die Prozess- / Thread-Terminologie ungeeignet verhalten.
Die POSIX-API, die üblicherweise beim Programmieren für Linux verwendet wird, kennt nur Prozesse und Threads, und daher kümmern sich die meisten Programme nicht wirklich darum, was ein Implementierungsdetail für sie ist, da die Verantwortlichkeiten zwischen Kernel und Benutzerbereich aufgeteilt werden. Ältere Implementierungen von Threads haben einige Implementierungsdetails verloren (ps zeigt Threads, Thread-ID und Prozess-ID, die sich vermischen, ...) und lieferten in einigen Fällen keine exakte POSIX-Semantik (Signalübertragung war problematisch IIRC).