关于Linux下的写时复制

关于写时复制

在Linux中要启动一个新进程的方式通常是:先调用fork()函数fork出一个新的进程,然后在 新的进程中调用exec()函数来启动新的程序从而达到启动新程序的目的,比如采用下面的代码实现。

int start_prog(char* prog,char* args[]) {  
    pid_t pid = fork(); // 创建子进程
    if(pid < 0)
        return -1;
    if(pid ==0) { // 子进程
        if(execv(prog, args)<0)
            return -1; // 加载新的程序
    } 
    else {
        return 1;
    }
}
int main() {
    char* args[] = { NULL };
    return  start_prog("/bin/ls", args);
}

我们知道进程间的内存地址空间是隔离的,fork()系统调用的结果是生成一个新的子进程,为了保证隔离性, 早期的UNIX采用在fork()将父进程的地址空间完整的复制一份。这个操作非常的耗时。 为了提高效率现代的Unix及Linux采用了一种称为写时复制的技术,其实也就是一种延迟操作的做法, 子进程和父进程在fork()时并不马上复制,而是暂时共享内存空间,随后只要父进程或者子进程试图写共享的内存就会产生一个异常, 这时内核才把内存空间进程复制,比如我们在Shell中启动一个程序时随后就会启动新的程序,启动后的程序将会覆盖旧的内存空间, 如果提前就复制了,那么这个复制操作其实是白做了,为此系统将这个操作优化为写时复制。

关于Linux下的写时复制_第1张图片

写时复制,发生写时才复制内存地址空间

关于Linux下的写时复制_第2张图片如果马上进行exec加载新的程序,那么复制地址就没必要了

你可能感兴趣的:(关于Linux下的写时复制)