フォーク後にtzset()
を呼び出すのが非常に遅いようです。フォーク前に親プロセスで最初にtzset()
を呼び出すと、遅いことがわかります。私のTZ
環境変数が設定されていません。私はdtruss
私のテストプログラムとそれは子プロセスがすべてのtzset()
の呼び出しのために読むことを明らかにしたが、親プロセスは一度だけそれを読む。このファイルアクセスは遅さの原因と思われますが、子プロセスで毎回アクセスする理由を特定できませんでした。ここでMac OS Xでフォークした後にtzset()が遅くなるのはなぜですか?
は私のテストプログラム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);
}
私がコンパイルされ、このようにfoo.cを実行:
[[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
私も再現する(Mac OS X 10.10.1を実行していますよ10.9.5)。
私はもともとルビー経由の遅さに気付きました(子プロセスでは時間#ローカルタイムが遅い)。
マイナー:Dではなく( ''よりも(開始、tv.tv_sec) 'difftimeをお勧めします可)(tv.tv_sec - start) 'となります。 'delta + =(double)...'の '(double)'は必要ありません。 – chux
パフォーマンスが悪い主な原因は、タイムゾーンファイルが** ** localtimeの呼び出しごとに変更されていないことを実際にチェックしていることです。システム設定がその下から変更できるように動作するのです。悪いフォークの振る舞いは、fork()で正しく機能しないファイル変更通知メカニズムの副作用である可能性があります。これは、コードを実行して楽器を動かすことに基づいていると仮定しているだけです。 – Petesh
私は通知理論が好きなので、もう少し調査し、以下の答えを掲載しました。 – Muir