【Linux】fork()函数典例分析

fork()函数典例分析

这篇博客主要内容为,借助本人《深入理解计算机系统》一书的老师给出的多个典例,对fork()函数进行一个由浅入深的理解,以下是本篇博客的主体目录。

  1. fork()简介
  2. fork() example mode:Easy
  3. fork() example mode:Hard
  4. fork() example mode:Hell
  5. 本篇总结

1.fork()简介

来自百度百科的对于fork()的介绍如是说到:

fork系统调用用于创建一个新进程,称为子进程,它与进程(称为系统调用fork的进程)同时运行,此进程称为父进程。创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。子进程使用相同的pc(程序计数器),相同的CPU寄存器,在父进程中使用的相同打开文件。

这样的介绍已经足够精简了,但是我认为更精简的理解就是:fork()在原有进程的基础上创建一个子进程,该子进程复制了父进程的数据空间、栈、堆等资源(包括I/O缓冲区)的副本(但并不共享存储空间,而是重新开辟存储空间)。

那么fork()有什么特点呢?

一次调用,两次返回:fork()对于父子进程有着不同的返回值:对父进程,它的返回值是子进程的pid;对子进程,它的返回值是0;当遇到创建子进程失败时,它的返回值是负数。因此,它的这个特点可以用于对父子进程分别进行操作。

了解完fork()是什么,话不多说,直接来看例子进行深入理解。

2.fork() example mode:Easy

void fork0() 
{
    if (fork() == 0) {
 printf("Hello from child\n");
    }
    else {
 printf("Hello from parent\n");
    }
}

这段代码的流程图如下:
fork0
可知,此段代码会有两个输出,一个是“Hello from child”来自子进程,一个是“Hello from parent"。但由于父子进程运行时的随机性,先后不能确定。

再来看另一段:

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

这段代码的流程图如下:
fork4
因此可知,本程序的一种输出为:

L0
L1
L2
Bye
Bye
Bye

3.fork() example mode:Hard

本段代码如下:

void fork9(){
	int child_status;
	if(fork()==0){
		printf("HC:hello from child\n");
		exit(0);
	}
	else{
		printf("HP:hello from parent\n");
		wait(&child_status);
		printf("CT:child has terminated\n");
	}
	printf("Bye\n");
}

这段代码的流程图如下:
fork9
由此可知,该程序的一种输出结果为:

HC: hello from child
HP: hello from parent
CT: child has terminated
Bye

这段代码中,就涉及到父进程等待子进程结束的问题,也就是运用了wait()函数的程序。当用到了wait()函数时,父进程会一直等待对应的子进程结束,才会运行接下来的代码。比如fork9()代码中所写的,父进程一直等到子进程exit(0)之后才会运行接下来的printf(“CT: child has terminated\n”);和printf(“Bye\n”)。

4.fork() example mode:Hell

本段代码如下:

void fork10()
{
    pid_t pid[N];
    int i, child_status;
    for (i = 0; i < N; i++)
 if ((pid[i] = fork()) == 0) {
     exit(100+i); /* Child */
 }
    for (i = 0; i < N; i++) { /* Parent */
 pid_t wpid = wait(&child_status);
 if (WIFEXITED(child_status))
     printf("Child %d terminated with exit status %d\n",
     wpid, WEXITSTATUS(child_status));
     else
     printf("Child %d terminate abnormally\n", wpid);
    }
}

本代码的运行流程图如下:
fork10
可知,本程序的主要内容就是创造5个子程序,同时按创建子进程的顺序结束子进程并依次返回104,103,102,101,100,等待子进程结束后父进程输出其终止状态。
本程序的运行结果为:

Child 2891 terminated with exit status 104
Child 2890 terminated with exit status 103
Child 2889 terminated with exit status 102
Child 2888 terminated with exit status 101
Child 2887 terminated with exit status 100

5.本篇总结

由四篇代码可以知道,fork()函数具有非常多的用途,当它与与之配套的多种函数(如:wait(),waitpid(),sleep(),WIFEXITSTATUS())一起使用时,程序将变得十分复杂。这时我们就需要使用流程图将我们的思路规划清晰。希望我这篇博客对大家有所帮助。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值