参考自: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. mac Latex dvipdfm 缺少字体错误 Failed to read UCS2/UCS4 TrueType cmap

    dvipdfmx 命令产生 ** ERROR ** Failed to read UCS2/UCS4 TrueType cmap... 错误的原因是没有把 simsun.ttf simkai.ttf ...

  2. WGET and CURL

    目录 WGET and CURL 对比 wget curl curl使用示例 WGET and CURL 对比 CURL 和WGET都可以用来下载文件,用法也类似:curl/wget [-option ...

  3. JMeter--PerfMon Metrics Collector监控内存及CPU

    1.需要准备的软件及插件 ServerAgent-2.2.1.zip JMeterPlugins-Standard-1.3.1.zip 2.jmeter上JMeterPlugins-Standard- ...

  4. asp.net mvc 中使用 iframe 加载相应的静态html页面进行显示

     <iframe src='<%=ResolveUrl("~/Content/HTML_file/Agreement.html")%>' <%@ Page ...

  5. javascript ES 6 class 详解

    Introduction 上篇文章大致介绍了一些ES6的特性,以及如何在低版本浏览器中使用它们.本文是对class的详解. 译自Axel Rauschmayer的Classes in ECMAScri ...

  6. 五、UML类图和六大原则-----《大话设计模式》

    一.单一职责原则     就一个类而言,应该仅有一个引起它变化的原因.     如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力.这种耦合 ...

  7. IOS命名

    NS开头的名称不要出现. NS系统名称开头. 命名缩写只用于通用专业术语,如URL,不可自创命名缩写,如Ctr.Msg.命名宁可长一些,也不要难于理解. 是否在看别人代码时各种缩写而不知其所以然?简短 ...

  8. SQL 转换函数

    1.字符串与字符串相加 字符串相加   得到的是拼接成一列的字符串类型 例如 select name+code from car       name是nvarchar  code也是nvarchar ...

  9. _T(x) _TEXT(x) L 代表什么?

    首先  <tchar.h>中 #ifdef  _UNICODE .... #define __T(x)      L ## x  //替换 #else   /* ndef _UNICODE ...

  10. codeforces Gym 100338E Numbers (贪心,实现)

    题目:http://codeforces.com/gym/100338/attachments 贪心,每次枚举10的i次幂,除k后取余数r在用k-r补在10的幂上作为候选答案. #include< ...