Chiamare tzset()
dopo la biforcazione sembra essere molto lento. Vedo la lentezza solo se prima chiamo il tzset()
nel processo genitore. La mia variabile di ambiente TZ
non è impostata. I dtruss
del mio programma di test e ha rivelato che il processo figlio legge /etc/localtime
per ogni chiamata tzset()
, mentre il processo padre la legge solo una volta. Questo accesso ai file sembra essere la causa della lentezza, ma non sono stato in grado di determinare perché accedesse ad esso ogni volta nel processo figlio.Perché tzset() è molto più lento dopo la foratura su Mac OS X?
Ecco il mio programma di test 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);
}
ho compilato ed eseguito foo.c come questo:
[[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
sto con Mac OS X 10.10.1 (riprodotto anche 10.9.5).
Originariamente ho notato la lentezza tramite ruby (Time # localtime slow in child process).
Minore: raccomandare 'difftime (tv.tv_sec, start)' invece di '(d ouble) (tv.tv_sec - start) '. '(double)' in 'delta + = (double) ...' non è necessario. – chux
Penso che il motivo principale per le scarse prestazioni sia che in realtà controlla che il file del fuso orario non abbia cambiato ** ogni ** chiamata in locale - sta facendo il mac come comportarsi come l'impostazione del sistema può cambiare da sotto. Il cattivo comportamento della forcella potrebbe essere un effetto collaterale del meccanismo di notifica della modifica dei file che non viene utilizzato correttamente attraverso un 'fork()' - questa è solo una supposizione basata sull'esecuzione del codice tramite strumenti e alcuni googling. – Petesh
Mi è piaciuta la teoria delle notifiche, quindi ho esaminato un po 'di più e ho postato una risposta qui sotto. – Muir