Wenn Threads dieselbe PID verwenden, wie können sie identifiziert werden?

Ich habe eine Abfrage im Zusammenhang mit der Implementierung von Threads in Linux.

Linux hat keine explizite Thread-Unterstützung. Im Benutzerbereich können wir eine Thread-Bibliothek (wie NPTL) zum Erstellen von Threads verwenden. Jetzt, wenn wir NPTL verwenden, unterstützt es 1: 1-Mapping.

Der coreel verwendet die function clone() , um Threads zu implementieren.

Angenommen, ich habe 4 Threads erstellt. Dann würde es bedeuten, dass:

  • Es wird 4 task_struct .
  • Innerhalb von task_struct wird die Freigabe von Ressourcen gemäß den zu (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) Argumenten (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND) .

Jetzt habe ich folgende Abfrage:

  1. Werden die 4 Threads die gleiche PID haben? Wenn jemand ausarbeiten kann, wie die PIDs geteilt werden.
  2. Wie werden die verschiedenen Threads identifiziert? Gibt es ein TID (Thread ID) Konzept?

Die vier Threads haben die gleiche PID, aber nur von oben betrachtet. Was Sie (als Benutzer) eine PID nennen, ist nicht das, was der coreel (von unten betrachtet) eine PID aufruft.

Im coreel hat jeder Thread seine eigene ID, eine PID (obwohl es möglicherweise sinnvoller wäre, diese als TID oder Thread-ID zu bezeichnen), und sie haben auch eine TGID (Thread-Gruppen-ID), die die PID des Threads ist Das hat den ganzen process in Gang gesetzt.

Wenn ein neuer process erstellt wird, erscheint er als ein Thread, bei dem sowohl die PID als auch die TGID dieselbe (neue) Nummer sind.

Wenn ein Thread einen anderen Thread startet , erhält dieser gestartete Thread seine eigene PID (der Scheduler kann sie also unabhängig planen), erbt jedoch die TGID vom ursprünglichen Thread.

Auf diese Weise kann der coreel problemlos Threads planen, unabhängig davon, zu welchem ​​process sie gehören, während Ihnen processe (Thread-Gruppen-IDs) gemeldet werden.

Die folgende Hierarchie von Threads kann helfen (a) :

  USER VIEW < -- PID 43 --> < ----------------- PID 42 -----------------> +---------+ | process | _| pid=42 |_ _/ | tgid=42 | \_ (new thread) _ _ (fork) _/ +---------+ \ / +---------+ +---------+ | process | | process | | pid=44 | | pid=43 | | tgid=42 | | tgid=43 | +---------+ +---------+ < -- PID 43 --> < --------- PID 42 --------> < --- PID 44 ---> KERNEL VIEW 

Sie können sehen, dass das Starten eines neuen processes (auf der linken Seite) Ihnen eine neue PID und eine neue TGID gibt (beide auf denselben Wert gesetzt), während das Starten eines neuen processes (auf der rechten Seite) Ihnen eine neue PID gibt, während Sie dieselbe beibehalten TGID als der Thread, der es gestartet hat.


(a) Zittere in Ehrfurcht vor meinen beeindruckenden grafischen Fähigkeiten 🙂

Threads werden mithilfe von PIDs und TGID (Thread group id) identifiziert. Sie wissen auch, welcher Thread ein Elternteil von wem ist, also teilt ein process seine PID mit allen Threads, die er startet. Thread-IDs werden normalerweise von der Thread-Bibliothek selbst verwaltet (z. B. Pthread usw.). Wenn die 4 Threads gestartet werden, sollten sie dieselbe PID haben. Der coreel selbst wird Thread-Scheduling und dergleichen behandeln, aber die Bibliothek ist diejenige, die die Threads verwalten wird (ob sie ausgeführt werden können oder nicht, abhängig von der Verwendung von Thread-Join- und Warte-Methoden).

Hinweis: Dies ist aus meiner Erinnerung an coreel 2.6.36. Meine Arbeit in den aktuellen coreel-Versionen befindet sich in der I / O-Ebene, daher weiß ich nicht, ob sich das seither geändert hat.

Linux bietet den Systemaufruf fork() mit der traditionellen functionalität, einen process zu duplizieren. Linux bietet auch die Möglichkeit, Threads mit dem Systemaufruf clone() zu erstellen. Allerdings unterscheidet linux nicht zwischen processen und Threads.