fork Function

本文详细介绍了fork函数的功能与使用方法,包括其返回值的意义、父子进程间的数据共享机制以及copy-on-write技术的应用。并通过一个示例程序展示了如何利用fork创建子进程,并分析了不同情况下输出结果的差异。

fork - create a child process

#include <unistd.h>

pid_t fork(void);
             //Returns:0 in child, process ID of child in parent, -1 on error

该函数返回了两次
子进程中通过getppid可以获得父进程的process ID。
父进程中通过fork返回值获得子进程process ID。
父子进程会继续执行fork之后的指令。

父子进程的堆栈和数据空间

  1. 子进程复制了父进程的数据空间,栈,堆。
  2. 共享text segment

copy on write(COW)

自从fork经常接着调用exec,当前很多实现不执行完整的父数据,栈,堆的复制。这些区域是父子进程以read-only方式共享的。在需要修改这些区域的时候,kernel会以page进行复制。

Linux中clone(2)也能创建新进程

允许调用者控制父子进程共享什么内容

Example:

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

int glob = 6;
int main(void)
{
    int var;
    pid_t pid;
    var = 88;
    printf("before fork\n");
    if((pid = fork()) < 0)
    {
        fprintf(stderr, "fork error!\n");
        exit(-1);
    }else if(pid == 0)//子进程
    {
        var++;
        glob++;
    }
    else//父进程
    {
        sleep(2);
    }
    printf("pid = %d, glob = %d, var = %d\n", getpid(), glob, var);
    exit(0);
}

结果

$./fork
before fork
pid = 3306, glob = 7, var = 89
pid = 3305, glob = 6, var = 88

$./fork > temp.out
cat temp.out
before fork
pid = 3306, glob = 7, var = 89
before fork
pid = 3305, glob = 6, var = 88

我们可以发现
第一种情况:我们只有一份printf打印的before fork
第二种情况:在fork之前,printf的数据被打印出来。此时,数据保存在缓冲区中,在调用fork之后,也被复制了一份。接下来调用的printf刷新了缓冲区
before fork
pid = 3305, glob = 6, var = 88
就被存到了文件中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

猎羽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值