2010-08-10 17 views
34

Wie bestimmt Linux die nächste PID, die es für einen Prozess verwendet? Der Zweck dieser Frage ist es, den Linux-Kernel besser zu verstehen. Haben Sie keine Angst, Kernel-Quellcode zu posten. Wenn PIDs sequenziell zugewiesen werden, wie füllt Linux die Lücken? Was passiert, wenn es zu Ende geht?Wie bestimmt Linux die nächste PID?

Zum Beispiel, wenn ich einen PHP-Skript von Apache ausführen, die ein <?php print(getmypid());?> die gleichen PID tut, wird während Hit Refresh für ein paar Minuten ausgedruckt werden. Dieser Zeitraum ist eine Funktion davon, wie viele Anfragen Apache empfängt. Selbst wenn es nur einen Client gibt, wird sich die PID letztendlich ändern.

Wenn sich die PID ändert, wird es eine enge Zahl sein, aber wie nahe? Die Nummer scheint nicht vollständig sequenziell zu sein. Wenn ich eine ps aux | grep apache bekomme ich eine ganze Reihe von Prozessen:

enter image description here

Wie Linux diese nächste Nummer wählen? Die vorherigen PIDs werden noch ausgeführt, ebenso wie die letzte PID, die gedruckt wurde. Wie wählt Apache diese PIDs wieder?

Antwort

48

Der Kernel weist PIDs im Bereich von (RESERVED_PIDS, PID_MAX_DEFAULT) zu. Dies geschieht sequenziell in jedem Namespace (Aufgaben in verschiedenen Namespaces können die gleichen IDs haben). Falls der Bereich erschöpft ist, wird die PID-Zuweisung umgebrochen.

Einige relevante Code:

Innen alloc_pid (...

)
for (i = ns->level; i >= 0; i--) { 
    nr = alloc_pidmap(tmp); 
    if (nr < 0) 
     goto out_free; 
    pid->numbers[i].nr = nr; 
    pid->numbers[i].ns = tmp; 
    tmp = tmp->parent; 
} 

alloc_pidmap()

static int alloc_pidmap(struct pid_namespace *pid_ns) 
{ 
     int i, offset, max_scan, pid, last = pid_ns->last_pid; 
     struct pidmap *map; 

     pid = last + 1; 
     if (pid >= pid_max) 
       pid = RESERVED_PIDS; 
     /* and later on... */ 
     pid_ns->last_pid = pid; 
     return pid; 
} 

Sie beachten Sie, dass PIDs im Rahmen des Kernels sind mehr als nur int Kennungen; Die relevante Struktur kann in /include/linux/pid.h gefunden werden. Neben der ID enthält sie eine Liste von Aufgaben mit dieser ID, einen Referenzzähler und einen Hash-Listenknoten für den schnellen Zugriff.

Der Grund dafür, dass PIDs im Benutzerbereich nicht sequenziell angezeigt werden, liegt darin, dass die Kernel-Planung möglicherweise einen Prozess zwischen Ihren Prozessaufrufen "fork()" ausgibt. Es ist in der Tat sehr üblich.

+0

+1 Sie sind ein böser Arsch, also gab ich Ihnen etwas anderes ... – rook

+0

Gibt es nay Weise, die ich die globalen und die Namespace-PIDs abbilden kann? –

11

Ich würde eher davon ausgehen, das Verhalten Sie beobachten stammt aus einer anderen Quelle:

Guter Web-Server in der Regel mehr Prozessinstanzen hat die Last der Anfragen zu balancieren. Diese Prozesse werden in einem Pool verwaltet und jedes Mal, wenn eine Anfrage eingeht, einer bestimmten Anfrage zugewiesen. Um die Leistung zu optimieren, weist Apache wahrscheinlich einem Bündel sequenzieller Anfragen desselben Clients denselben Prozess zu. Nach einer bestimmten Anzahl von Anforderungen wird dieser Prozess beendet und ein neuer erstellt.

Ich glaube nicht, dass mehr als eine Prozesse in Folge die gleiche PID von Linux zugewiesen werden.

Wie Sie sagen, dass die neue PID wird nah an der letzten, ich denke, Linux einfach jedem Prozess die letzte PID + 1 zugeordnet. Aber es gibt Prozesse Pop-up und wird ständig im Hintergrund von Anwendungen und beendet Systemprogramme, so können Sie die genaue Anzahl des Apache-Prozesses, der als nächstes gestartet wird, nicht vorhersagen.

Abgesehen davon sollten Sie nicht verwenden Sie irgendeine Annahme über PID-Zuweisung als Basis für etwas, das Sie implementieren. (Siehe auch Sanmais Kommentar.)

+0

Ich denke, das ist teilweise richtig, leider haben Sie keine Beweise, diese Antwort zu unterstützen. – rook

+0

Jetzt habe ich, siehe die anderen Antworten. :-) – chiccodoro

+0

btw ich war der (+1) – rook

9

PIDs are sequential auf den meisten Systemen. Sie können dies sehen, wenn Sie mehrere Prozesse auf sich selbst im Leerlauf starten.

z.B. aufbrauchen Pfeil Geschichte erinnern, um wiederholt einen Befehl ausführen, der seine eigene PID druckt:

$ ls -l /proc/self 
lrwxrwxrwx 1 root root 0 Mar 15 19:32 /proc/self -> 21491 
$ ls -l /proc/self 
lrwxrwxrwx 1 root root 0 Mar 15 19:32 /proc/self -> 21492 
$ ls -l /proc/self 
lrwxrwxrwx 1 root root 0 Mar 15 19:32 /proc/self -> 21493 
$ ls -l /proc/self 
lrwxrwxrwx 1 root root 0 Mar 15 19:32 /proc/self -> 21494 

Verlassen Sie sich nicht auf diese: aus Sicherheitsgründen einige Leute Kernel laufen, die zusätzliche CPU-Zeit verbringen, um zufällig neue PIDs zu wählen.

+0

Dies scheint nicht wahr zu sein. – rook

+0

@ The Rock: Warum? – chiccodoro

+0

@chiccodoro Screenshot geschrieben. – rook

3

PIDs können nach dem Zufallsprinzip zugewiesen werden. Es gibt a number of ways, um das zu erreichen.

+0

Soweit ich weiß, PID Randomisierung wurde von Linux Kernel-Entwicklungsteam wegen der Sicherheit durch Unklarheit abgelehnt. – Akshay

Verwandte Themen