在Unix/Linux中用fork函数创建一个新的进程。进程是由当前已有进程调用fork函数创建,分叉的进程叫子进程,创建者叫父进程。该函数的特点是调用一次,返回两次,一次是在父进程,一次是在子进程。两次返回的区别是子进程的返回值为0,父进程的返回值是新子进程的ID。子进程与父进程继续并发运行。如果父进程继续创建更多的子进程,子进程之间是兄弟关系,同样子进程也可以创建自己的子进程,这样可以建立起定义关系的进程之间的一种层次关系。

  程序包含位于内存的多个组成部分,执行程序的过程将根据需要来访问这些内容,包括文本段(text segment)、数据段(data segments)、栈(stack)和堆(heap)。文本段中存放CPU所执行的命令,数据段存放进程操作的所有数据变量,栈存放自动变量和函数数据,堆存放动态内存分配情况数据。当进程被创建时,子进程收到父进程的数据副本,包括数据空间、堆、栈和进程描述符。

程序1:创建一个子进程,子进程对继承的数据进行修改,然后分别输出父子进程的信息。程序如下:


fork函数执行后程序结构图如下:

子进程与父进程并行执行,因此在父进程中sleep(10),让子进程先执行,然后再执行父进程。

程序执行结果如下所示:

如何创建多个子进程呢?在开发并发服务器时,用到的进程池模型需要先创建指定书目的子进程。举个例子,假如我们现在需要创建2个子进程,很容易想到的是调用一个循环,执行fork函数2次即可。尝试一下是否可行呢?代码如下:

程序执行结果如下:

从结果来看,子进程的数目不是2而是3,这是为什么呢?先简单的分析一下:从结果看出父进程ID为10669,子进程的ID分别为:10670、10671、10672。

父子进程之间的关系如下:

ID为10670的子进程也调用fork函数,创建了一个进程。因为fork函数创建的进程是父进程的一份拷贝,保存了当前的数据空间、堆、栈及共享代码区域。正确的方式应该是在子进程中跳出,停止继续fork。改进的代码如下:

程序执行结果如下:

从结果可以看出这父进程(ID为10789)创建了两个子进程(ID分别为:10790、10791)。

现有有这样一个面试题,程序如下:

 1 #include <stdio.h>
2 #include <unistd.h>
3 #include <stdlib.h>
4 #include <sys/types.h>
5
6 int main()
7 {
8 pid_t pid1;
9 pid_t pid2;
10
11 pid1 = fork();
12 pid2 = fork();
13
14 printf("pid1=%d,pid2=%d\n",pid1,pid2);
15 exit(0);
16 }

要求如下:
 已知从这个程序执行到这个程序的所有进程结束这个时间段内,没有其它新进程执行。
 1、请说出执行这个程序后,将一共运行几个进程。
 2、如果其中一个进程的输出结果是“pid1:1001, pid2:1002”,写出其他进程的输出结果(不考虑进程执行顺序)。

  这个题目考查fork函数的理解。fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程,父子进程并行的执行剩下的部分。

程序的执行过程如下:

(1)程序开始执行时候系统分配一个进程进行执行,称该进程为主进程P,进程ID题目未给,

(2)主进程执行到第一个fork函数的时候,创建一个新的子进程P1,有题目可知进程ID为1001,fork函数有两个返回值,返回pid=0代表子进程P1,pid1>0代表父进程P。

(3)现在有两个进程P和P1,分别执行剩下部分,

(4)P进程(父进程,所以pid1=1001)调用fork创建子进程P2,返回两个值中pid2=1002表示P2的进程ID返回给父进程P,pid2=0子进程P2本身,所以输出pid1=1001,         pid2=1002和pid1=1001,pid2=0。

(5)P1进程(子进程,所以pid1=0)调用fork创建子进程P3,进程ID类推为1003,返回两个值中pid2=1003表示P3的进程ID返回给父进程P1,pid2=0标识进程P3本身。所以输出pid1=0,pid2=1003和pid1=0,pid2=0。

(6)执行整个结束。

根据以上分析可知答案:

1、一共执行了四个进程。(P0, P1, P2, P3)

2、另外几个进程的输出分别为:

 pid1:1001, pid2:0

 pid1:0, pid2:1003

 pid1:0, pid2:0

上机测试如下:

测试结果如下:

测试结果虽然不是1001,但是可以看出理论分析过程是正确的。

题目来自:http://www.cnblogs.com/leoo2sk/archive/2009/12/11/talk-about-fork-in-linux.html

fork函数的更多相关文章

  1. Linux C 中 fork() 函数详解

    一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork() 函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同 ...

  2. 进程间通信--fork函数

    #include <unistd.h> pid_t fork(void); fork() creates a new process by duplicating the calling ...

  3. Fork函数初识

    fork函数用于创建子进程,典型的调用一次,返回两次的函数.其中调用进程返回子进程的PID,而子进程则返回0.但是两个进程的执行顺序是不定的. fork函数调用完成以后父进程的虚拟存储空间被拷贝给了子 ...

  4. fork()函数详解

    原文链接:http://blog.csdn.net/jason314/article/details/5640969  一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函 ...

  5. Linux—fork函数学习笔记

    fork()函数 在赋值语句pid = fork();之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的代码部分完全相同.> 两个进程中,原先就存在的那个被 ...

  6. linux fork函数与vfork函数,exit,_exit区别

    man vfork: NAME vfork - create a child process and block parent SYNOPSIS #include <sys/types.h> ...

  7. fork()函数

    现代操作系统提供的三种构造并发程序的方法: •进程 一个进程实体包括:代码段,数据段, 进程控制块 fork()函数:通过系统调用创建一个与原来一模一样的子线程,[用来处理请求信号,而父进程继续一直处 ...

  8. 进程控制之fork函数

    一个现有进程可以调用fork函数创建一个新进程. #include <unistd.h> pid_t fork( void ); 返回值:子进程中返回0,父进程中返回子进程ID,出错返回- ...

  9. fork 函数 和vfork 函数的区别

    问题描述:         fork 函数 和vfork 函数的区别 问题解决: fork函数使用: 注:         以上printf 属于标准IO库带缓冲,如果标准输出链接到终端设备,则它是行 ...

随机推荐

  1. ompparticles.cpp:(.text+0x322): undefined reference to `omp_set_num_threads'

    参考 http://www.code-by.org/viewtopic.php?f=54&t=163

  2. 重新想象 Windows 8 Store Apps (54) - 绑定: 增量方式加载数据

    [源码下载] 重新想象 Windows 8 Store Apps (54) - 绑定: 增量方式加载数据 作者:webabcd 介绍重新想象 Windows 8 Store Apps 之 绑定 通过实 ...

  3. ASP.NET或WinFrom中获取汉子的拼音首字母

    1.获得一个字符串的每个字的拼音首字母构成所需的字符串 #region  获取首字母 /// <summary>         /// 这个办法是用来获得一个字符串的每个字的拼音首字母构 ...

  4. ActiveReports 报表应用教程 (5)---解密电子商务领域首张电子发票的诞生(套打报表)

    6月27日京东商城发布了中国电子商务领域首张电子发票,同时宣布相关系统正式上线,这标志着中国电子商务的步伐又向前迈出了重要的一步.目前“电子发票”覆盖的服务范围是在北京地区购买图书.音像商品的个人消费 ...

  5. Android从零开始——Android开发环境的安装

    Android开发环境的安装 1 IDE Android可以使用开发的IDE有Eclipse 或者 Android Studio.Android Studio还处于v 0.1.x版本,是early a ...

  6. 使用openssl创建自签名证书及部署到IIS教程

    概要 本文讲解三个部分:1. 创建自签名证书2. 创建自己的证书颁发机构3. 以及如何配置IIS 创建自签名证书 首先,创建一个私钥文件: openssl genrsa -out myselfsign ...

  7. 解决maven项目update project会更改jdk版本问题

    一.问题描述             在Eclipse中新建了一个Maven工程, 然后更改JDK版本为1.6, 结果每次使用Maven > Update project的时候JDK版本都恢复成 ...

  8. 通过FTP连接Azure上的网站

    下载发布文件 使用记事本(或其他文本工具)打开 找到ftp连接地址以及用户名.密码 使用ftp工具进行连接 输入相应参数,连接即可

  9. sharepoint 中waiting screen dialog的使用方法(JSOM)

    sharepoint中有一个种wait screen的弹出框,其实就是一直转圈,告诉你等待一会儿时间.用法如下: 弹出: var watiDialog = SP.UI.ModalDialog.show ...

  10. teambition的热血团队

    一群热血年轻人开发了一套项目协作软件teambition,无意帮他们宣传,更多见网址www.teambition.com. 网站上简短的一段话,深深的打动了我.他们说teambition: 由热爱工作 ...