Das Aufrufen von tzset()
nach Verzweigung scheint sehr langsam zu sein. Ich sehe nur die Langsamkeit, wenn ich zuerst im Elternprozess vor dem Verzweigen tzset()
aufrufen. Meine TZ
Umgebungsvariable ist nicht festgelegt. I dtruss
'd mein Testprogramm und es ergab, dass der Kindprozess liest /etc/localtime
für jeden Aufruf tzset()
, während der Elternprozess nur einmal liest. Dieser Dateizugriff scheint die Ursache für die Langsamkeit zu sein, aber ich konnte nicht feststellen, warum er jedes Mal im untergeordneten Prozess darauf zugreift.Warum ist tzset() nach dem Forken auf Mac OS X viel langsamer?
Hier ist mein Testprogramm foo.c:
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
void check(char *msg);
int main(int argc, char **argv) {
check("before");
pid_t c = fork();
if (c == 0) {
check("fork");
exit(0);
}
wait(NULL);
check("after");
}
void check(char *msg) {
struct timeval tv;
gettimeofday(&tv, NULL);
time_t start = tv.tv_sec;
suseconds_t mstart = tv.tv_usec;
for (int i = 0; i < 10000; i++) {
tzset();
}
gettimeofday(&tv, NULL);
double delta = (double)(tv.tv_sec - start);
delta += (double)(tv.tv_usec - mstart)/1000000.0;
printf("%s took: %fs\n", msg, delta);
}
ich zusammengestellt und foo.c wie folgt ausgeführt:
[[email protected] scratch]$ clang -o foo foo.c
[[email protected] scratch]$ env -i ./foo
before took: 0.002135s
fork took: 1.122254s
after took: 0.001120s
ich Mac OS X 10.10.1 renne (auch reproduziert am 10.9.5).
Ich bemerkte ursprünglich die Langsamkeit über Ruby (Zeit # localtime langsam im Kind-Prozess).
Minor: empfehlen 'difftime (tv.tv_sec, Start)' 'statt (d double) (tv.tv_sec - start) '. '(double)' in 'delta + = (double) ...' wird nicht benötigt. – chux
Ich denke, der Hauptgrund für die schlechte Leistung ist, dass es tatsächlich überprüft, dass die Zeitzone Datei hat sich nicht ** jeden ** Ortszeit Anruf geändert - es tut das Mac-Verhalten wie die Systemeinstellung von darunter ändern kann. Das schlechte Fork-Verhalten kann ein Nebeneffekt des Mechanismus zur Benachrichtigung über Dateiänderungen sein, der über 'fork()' nicht ordnungsgemäß funktioniert - dies ist nur eine Annahme, die darauf beruht, dass der Code durch Instrumente und etwas Googlen ausgeführt wird. – Petesh
Ich mochte die Benachrichtigungstheorie, also untersuchte ich etwas mehr und schrieb eine Antwort unten. – Muir