Ich habe ein System, in dem zwei identische Prozesse ausgeführt werden (nennen wir sie Replikate). Wenn ein Replikat signiert wird, wird es sich mit dem Aufruf fork()
duplizieren. Ein dritter Prozess wählt einen der Prozesse aus, um zufällig zu töten, und signalisiert dann dem anderen, einen Ersatz zu erzeugen. Funktional funktioniert das System gut; Es kann Repliken den ganzen Tag außer dem Leistungsproblem töten/respawnen.Gabel() undicht? Es dauert länger und länger, um einen einfachen Prozess zu verzweigen
Der Anruf fork()
dauert länger und länger. Das folgende ist das einfachste Setup, das das Problem weiterhin anzeigt. Der Zeitpunkt wird in der folgenden Grafik dargestellt:
Die Replik des Codes ist die folgende:
void restartHandler(int signo) {
// fork
timestamp_t last = generate_timestamp();
pid_t currentPID = fork();
if (currentPID >= 0) { // Successful fork
if (currentPID == 0) { // Child process
timestamp_t current = generate_timestamp();
printf("%lld\n", current - last);
// unblock the signal
sigset_t signal_set;
sigemptyset(&signal_set);
sigaddset(&signal_set, SIGUSR1);
sigprocmask(SIG_UNBLOCK, &signal_set, NULL);
return;
} else { // Parent just returns
waitpid(-1, NULL, WNOHANG);
return;
}
} else {
printf("Fork error!\n");
return;
}
}
int main(int argc, const char **argv) {
if (signal(SIGUSR1, restartHandler) == SIG_ERR) {
perror("Failed to register the restart handler");
return -1;
}
while(1) {
sleep(1);
}
return 0;
}
Je länger das System läuft, desto schlimmer wird es.
Es tut uns leid, eine bestimmte Frage zu haben, aber hat jemand irgendeine Idee/Hinweise, was vor sich geht? Es scheint mir, dass es im Kernel ein Ressourcenleck gibt (also das Linux-Kernel-Tag), aber ich weiß nicht, wo ich anfangen soll.
Was habe ich versucht:
- kmemleak Versuchte, die nichts zu fangen haben. Dies bedeutet, dass bei einem Speicherleck immer noch erreichbar ist.
/proc/<pid>/maps
wächst nicht.- Derzeit läuft der 3.14 Kernel mit RT-Patch (beachten Sie, dies passiert mit nicht-RT-und RT-Prozesse), und haben auch am 3.2 versucht.
- Zombie-Prozesse sind kein Problem. Ich habe versucht, eine Version, in der ich einen anderen Prozess als ein Unterreader mit prctl
- Ich bemerkte zuerst diese Verlangsamung in einem System, in dem die Timing-Messungen sind außerhalb des neu gestarteten Prozesses; gleiches Verhalten.
Irgendwelche Hinweise? Alles, was ich zur Verfügung stellen kann, um zu helfen? Vielen Dank!
Das untergeordnete Element ist nur eine exakte Kopie bis zu dem Zeitpunkt, zu dem der neue Prozess gestartet wird, bzw. bis zum ersten Speicherbefehl. Danach muss der Speicher Kopien erstellen und schreiben. –
Im ganzen System komme ich um dies mit Hilfe von mlockall und dann gehen/Proc/Pid/Maps Dummy schreibt. Sowohl im Gesamtsystem als auch im Code, den ich hier anbiete, bleibt das Performance-Problem mit der Gabel bestehen. – superdesk
Haben Sie den Befehl ps verwendet, um zu sehen, was gerade ausgeführt wird (in der Regel wiederholt das Dienstprogramm 'top' das für Sie) und wie viel Zeit wird in jedem laufenden Prozess verbraucht? In meinem Code sehe ich keine Weitergabe des Signals user1, so dass es zweifelhaft ist, dass alle untergeordneten Prozesse getötet werden. – user3629249