40-Linux_fork复制进程及写时拷贝

文章目录

  • fork复制进程及写时拷贝
    • 一.fork
    • 二. 写时拷贝技术

fork复制进程及写时拷贝

一.fork

fork是把已有的进程复制一份,当然把PCB也复制了一份,然后申请一个PID,子进程的
PID(父进程的)+1;
子进程的PID=父进程的PID+1;

40-Linux_fork复制进程及写时拷贝_第1张图片

#include
#include
#include
#include

int main()
{
    printf("Begin....\n");
    pid_t id=fork();
    if(id<0)
    {
        printf("error\n");
    }
    else if(id==0)
    {
        printf("child ,id=%d,child=%d,father=%d\n",id,getpid(),getppid());
    }
    else
    {
        printf("father,id=%d,child=%d,father=%d\n",id,getpid(),getppid());
    }
    printf("end\n");
    return 0;
}

如果父子进程想要做不同的事情,那么我们通过返回值来判断;

返回值==0 子进程
返回值>0 父进程
返回值<0 错误

#include
#include
#include
#include
#include

int main()
{
    char *s=NULL;
    int n=0;

    pid_t id=fork();
    assert(id!=-1);

    if(id==0)
    {
        s="child";
        n=3;
    }
    else
    {
        s="parent";
        n=7;
    }

    int i=0;
    for(;i<n;i++)
    {

        printf("s=%s\n",s);
        sleep(1);
    }
    exit(0);
}

getppid:得到一个进程的父进程的PID;
getpid:得到当前进程的PID

二. 写时拷贝技术

对fork复制进程做了一个优化----写时拷贝技术

40-Linux_fork复制进程及写时拷贝_第2张图片

写时拷贝是一种可以推迟甚至免除拷贝数据的技术
传统的 fork()系统调用直接把所有的资源复制给新创建的进程。这种实现过于简单并且效率低下,因为它拷贝的数据也许并不共享,更的情况是,如果新进程打算立即执行一个新的映像,那么所有的拷贝都将前功尽弃。Linux 的 fork() 使用写时贝 (copy-on-write)页实现。写时拷贝是一种可以推迟甚至免除拷贝数据的技术。内核此时并不复制整个进程地址空间,而是让父进程和子进程共享同一个拷贝。
只有在需要写人的时候,数据才会被复制,从而使各个进程拥有各自的拷贝。也就是说,资源的复制只有在需要写人的时候才进行,在此之前,只是以只读方式共享。这种技术使地址空间上的页的拷贝被推迟到实际发生写入的时候才进行。在页根本不会被写入的况下(举例来说fork()后立即调用 exec()它们就无须复制了。
fork() 的实际开销就是复制父进程的页表以及给子进程创建唯一的进程描述符。在一般情况下,进程创建后都会马上运行一个可执行的文件,这种优化可以避免拷贝大量根本就不会被使用的数据(地址空间里常常包含数十兆的数据)。由于 Unix 强调进程快执行的能力,所以这个优化是很重要的。

你可能感兴趣的:(Linux,linux,运维,服务器)