参考自:http://blog.csdn.net/dog_in_yellow/archive/2008/01/13/2041079.aspx

以前一直迷惑,什么叫一次调用,两次返回。通过上网搜索,终于知其原由。现将自己的理解记录于此。
       准备知识:
              内存中的进程包括三个部分:可执行文件(即程序),相关数据(包括变量,内存空间,缓冲区等),上下文环境(个人理解为从哪儿来,到哪儿去)。我们知道,电脑CPU资源有限,单核就只有一个,多核也不是无限多。而当前运行的程序个数总是多于CPU个数的(这个应该是可以想得通的,没有哪个制造商或个人那么阔气而浪费CPU)。因此在操作系统的调度之下,一个程序一般不会从头执行到尾而不间断,系统会按照程序执行的顺序、优先级别等来确实由哪个程序占用当前CPU。而被间断的那些程序就需要保存间断时刻的状态(即进程的三个部分都要记录下来),以便再次执行能够完全恢复到间断以前,如果间断的时间足够短,应该给人很流畅的感觉,这也就是为什么,我们能够一边听音乐,一边看这篇文章的缘故。我猜,这也是为什么运行在内存中的程序会被称为进程的缘故。

这样,我们就可以开始讨论fork函数了。假设一个进程中有一句代码p=fork()。

我们称当前调用p=fork()的进程为父进程,父进程pid号可以用getpid()获取。fork()返回一个值给变量p,此时p正常情况下应该是一个正整数,表示fork()新产生的子进程的pid号。

fork()产生的那个子进程和父进程完全相同(至少在父进程调用fork()那一瞬间是相同的),而且也是完全独立的(即执行的先后顺序完全由操作系统调度,且父进程不一定比子进程先执行完)。fork()函数并不同于一般的函数,父进程并不会等fork函数产生的子进程完全执行完再执行pid=fork()后面的代码。或者,可以理解为fork()的作用就是产生一个子进程,至于子进程是否运行、如何运行与它没关系。

现讨论子进程的执行。我们知道,既然fork()是复制父进程,那么p=fork()语句之前的情况应该是完全一致。在父进程中p变量得到的是子进程的pid号,但是在子进程中同样有这样一个p变量,它的值是不是也是子进程的pid号呢?这是关键所在! 事实上,子进程中的p变量得到的值不是子进程的pid号,而是0。子进程的pid号完全可以用getpid()在子进程中得到。这也是为什么称fork()一次调用,两次返回,即最后的结果就等价于:一个程序被调用两次形成两个进程,在p=fork()之前,两个进程完全一样,到这一句时,一个进程中p变量值为另一个进程的pid号,而另一个进程中p变量值为0,在这之后,两个进程分道扬镳,再无任何瓜葛。(注意,两个进程可以由同一个程序引起。)

fork()函数,一次调用,两次返回的更多相关文章

  1. 鸿蒙内核源码分析(fork篇) | 一次调用,两次返回 | 百篇博客分析OpenHarmony源码 | v45.03

    百篇博客系列篇.本篇为: v45.xx 鸿蒙内核源码分析(Fork篇) | 一次调用,两次返回 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管理内 ...

  2. [转帖]Linux下fork函数及pthread函数的总结

    Linux下fork函数及pthread函数的总结 https://blog.csdn.net/wangdd_199326/article/details/76180514 fork Linux多进程 ...

  3. fork函数详解

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

  4. 你好,C++(27)在一个函数内部调用它自己本身 5.1.5 函数的递归调用

    5.1.5 函数的递归调用 在函数调用中,通常我们都是在一个函数中调用另外一个函数,以此来完成其中的某部分功能.例如,我们在main()主函数中调用PowerSum()函数来计算两个数的平方和,而在P ...

  5. UNIX环境高级编程学习笔记(十)为何 fork 函数会有两个不同的返回值【转】

    转自:http://blog.csdn.net/fool_duck/article/details/46917377 以下是基于 linux 0.11 内核的说明. 在init/main.c第138行 ...

  6. 关于fork( )函数父子进程返回值的问题

    fork()是linux的系统调用函数sys_fork()的提供给用户的接口函数,fork()函数会实现对中断int 0x80的调用过程并把调用结果返回给用户程序. fork()的函数定义是在init ...

  7. 每次调用fork()函数之后,父线程和创建出的子线程都是从fork()后开始执行

    Linux下多少个"-"将被打印: 1 2 3 4 5 6 7 8 int main(void){   int i;   for(i=0;i<4;i++){   fork() ...

  8. python学习笔记10(函数一): 函数使用、调用、返回值

    一.函数的定义 在某些编程语言当中,函数声明和函数定义是区分开的(在这些编程语言当中函数声明和函数定义可以出现在不同的文件中,比如C语言),但是在Python中,函数声明和函数定义是视为一体的.在Py ...

  9. 利用jQuery扩展接口为jQuery框架定义了两个自定义函数,然后调用这两个函数

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

随机推荐

  1. Hive_Hive的管理_远程服务

    远程服务启动方式 - 端口号10000 - 启动方式: #hive --service hiveserver & 以JDBC或ODBC的程序登陆到hive中操作数据时,必须选用远程服务启动方式 ...

  2. <?php } ?> 标记

    只是为了分离php 和html 代码的一种书写方法. 你要知道 一段程序代码 function fool(){//内容}是这么组成的那么当有html代码的时候就需要先暂时将php的开始部分给分开(不分 ...

  3. 系统讲解一下,Dao,Entity,Servlet,Action各自有什么东西-Java/Web开发

    dao 主要是一些接口,里面定义了一些用于增删改查的方法名 daoImpl 就是对dao的具体实现 Service 同上,也是一些接口,主要是用来调用dao层的一些方法,所以这里定义的方法一般都定义好 ...

  4. 基于.net core封装的xml序列化,反序列化操作

    需求: 由于在.net core中去除了Xml序列化XmlSerializer操作类.因此,在于一此数据传输当中出,需要用到对xml格式字符串的处理问题.因此封装了一个xml序列化与反序列化操作的类库 ...

  5. android开发学习 ------- 【转】 android中的单例模式 (详解)

    https://blog.csdn.net/u011418943/article/details/60139644     这篇文章 前因后果 都说出来了 ,值得学习. https://blog.cs ...

  6. Idea安装以及破解

    软件安装包和破解工具安装包 链接 链接:https://pan.baidu.com/s/1TpCiaSsAz_I9gXyOnwKK9g 密码:qc49 1.下载完Idea工具后,点击.exe文件,进行 ...

  7. AJPFX总结hashmap和hashtable的区别

    Hashtable和HashMap类有三个重要的不同之处.第一个不同主要是历史原因.Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现. ...

  8. Java中IO流文件读取、写入和复制

    //构造文件File类 File f=new File(fileName); //判断是否为目录 f.isDirectory(); //获取目录下的文件名 String[] fileName=f.li ...

  9. [BZOJ2434][Noi2011]阿狸的打字机 AC自动机+树状数组+离线

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2434 题目中这种多个串匹配的问题,一下子就想到了AC自动机.然后发现如果要建立AC自动机, ...

  10. JS核心

    JS核心 1.实例化对象 objectName = new objectType (param1 [,param2] ...[,paramN]) 参数  objectName 新对象实例的名称. ob ...