csapp:fork系统调用典例详解

fork()性质

  • 一次调用,两次返回。返回值是0则是子进程,>0为父进程

  • 父、子进程是两个独立的进程,虚拟地址是相同但独立的
  • 并发执行
  • 共享文件

fork()之后内核会做:

  • 给子进程分配新的内存块
  • 将父进程部分内容拷贝给子进程,包括指令、数据、缓冲区、堆栈等
  • 添加子进程到系统进程列表
  • fork()返回,开始调度器调度

实际上,并没有真的全都“复制”一份,父进程只复制了PCB块(进程控制块),其他的代码段、数据段、用户堆栈内存空间并没有复制一份,而是与子进程共享。只有当子进程在运行中出现写操作时,才会产生中断,并为子进程分配内存空间。由于父进程的PCB和子进程的一样,所以在PCB中断中所记录的父进程占有的资源,也是与子进程共享使用的。

使用方法

pid_t pid=fork();  

例题详解 

例一

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h> 
#include <signal.h>

void fork2()
{
    printf("L0\n");
    fork();
    printf("L1\n");    
    fork();
    printf("Bye\n");
}

int main()
{
    fork2();
    return 0;
}

进程图:

输出:

补充:使用fork()函数时,提示符为什么会在子进程结束之前运行?

因为父进程是在当前shell命令执行的,父进程结束后就返回了shell。

小总结:

循环n遍,进程数(包括主进程)为2^n个

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main(int argc, char* argv[])
{ 
    int i;
    int n=argv[1][0]-'0';
    for(i=0;i<n;i++)
    	fork();
    printf("hello\n");
    return 0;
}

结果图: 

   

例二

void fork4()
{
    printf("L0\n");
    if (fork() != 0) 
    {
        printf("L1\n");
        if (fork() != 0)
        printf("L2\n");
    }
    printf("Bye\n");
}

 进程图:

结果:

 

例三

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{ 
    int i;
    for(i=0;i<2;++i)
    {
        fork();
        printf("-");
    }  
    return 0;
}

进程图: 

结果:

多输出-原因:

printf的缓冲机制

printf某些内容时,操作系统仅仅是把该内容放到了stdout的缓冲队列里了,并没有实际的写到屏幕上。但是,只要看到有\n或EOF 则会立即刷新stdout,因此就马上能够打印了。 

再来看一下有\n情况:

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{ 
    int i;
    for(i=0;i<2;++i)
    {
        fork();
        printf("-\n");
    }  
    return 0;
}

进程图:

结果:

可以看出正常输出了6个-,因为每次都及时输出刷新缓存了。

例四

#include<stdio.h>
#include<sys/types.h>
#include<unistd.h>
int main()
{ 
    fork()&&fork()||fork();
    printf("hello\n");
    return 0;
}

对于A&&B||C,只要清楚A&&B为真时,不会再执行C了;A为假时不会再执行B了,因为表达式的真假已经唯一确定了。

进程图:

结果图:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值