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

fork函数用于复制进程,子进程继承父进程的大部分状态,包括PCB。写时拷贝技术是fork的一个优化,它延迟了数据的复制,仅在尝试写入时才进行,减少了不必要的内存开销。这种技术在进程创建后立即执行exec时特别有用,避免了大量数据的复制。
摘要由CSDN通过智能技术生成

fork复制进程及写时拷贝

一.fork

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

在这里插入图片描述

#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#include<unistd.h>

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<stdio.h>
#include<assert.h>
#include<unistd.h>
#include<string.h>
#include<stdlib.h>

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复制进程做了一个优化----写时拷贝技术

在这里插入图片描述

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值