fork 似乎在不必要时复制

fork seems to copy when unnecessary

我正在尝试 fork 的 CoW(查看编辑以了解更详细的背景,这可能完全不相关

#include <stdio.h>
#include <time.h>
#include <unistd.h>

#define N 262144
struct {
    int n;
    int padding[1023];
} arr[N];
int main() {
    int i, sp = 0, t, tx = clock();
    for (i=0; i<N; ++i) arr[i].n = i;
    printf ("Init Time: %d\n", clock()-tx);
    #if 1
        sp = fork();
        if(!sp) _exit(0);
        waitpid(sp, &sp, 0);
    #endif
    // 5045 without fork
    // 104192 with fork
    t = clock();
    for (i=0; i<N; ++i) arr[i].n = -i;
    printf ("Runner %d Time: %d\n", sp, clock() - t);
    getchar();
    return 0;
}

fork 使以后的内存访问变慢。

fork 复制速度变慢了吗?如果是这样,为什么?我 运行 Ubuntu 20.04.3 LTS

/usr/bin/time -v 下尝试 运行 并观察 Minor (reclaiming a frame) page faults: 行。

即使 child 立即退出,叉子也会使其翻倍。

增加的时间似乎完全是由于这些页面错误。

据推测,在分叉时,内核将页面设置为写入时出错,以期望需要复制。 如果 child 在此类页面错误时已死,则复制的需要被取消(该页面不再与任何人共享,因此无需费心复制它),但您仍然需要为页面错误命中付出代价.

现在,如果您让 child 保持活动状态,那么页面错误处理程序也应该需要进行复制,而且实际上,保持 child 活动会增加循环持续时间数次。那应该是完整的 copy-on-write.

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>

#define N 262144
struct {
    int n;
    int padding[1023];
} arr[N];
int main() {
    int i, t, tx = clock();
    pid_t sp=0;
    for (i=0; i<N; ++i) arr[i].n = i;
    printf ("Init Time: %ld\n", clock()-tx);

    #if 1
    if(0>(sp = fork())) return 1;
    enum  { KEEP_THE_KID_EH = 1 };
    if(!sp){ if(KEEP_THE_KID_EH){ for(;;) pause(); }  exit(0); }
    #endif

    t = clock();
    for (i=0; i<N; ++i) arr[i].n = -i;
    printf ("Runner %ld Time: %ld\n", (long)sp, clock() - t);
    /*getchar();*/
    if(sp) kill(sp,SIGTERM);
    return 0;
}

我的时间是:

7371 without fork
189073 with fork
1092145 with fork and the kid kept