fork()函数,一次调用,两次返回
参考自: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()函数,一次调用,两次返回的更多相关文章
- 鸿蒙内核源码分析(fork篇) | 一次调用,两次返回 | 百篇博客分析OpenHarmony源码 | v45.03
百篇博客系列篇.本篇为: v45.xx 鸿蒙内核源码分析(Fork篇) | 一次调用,两次返回 | 51.c.h .o 进程管理相关篇为: v02.xx 鸿蒙内核源码分析(进程管理篇) | 谁在管理内 ...
- [转帖]Linux下fork函数及pthread函数的总结
Linux下fork函数及pthread函数的总结 https://blog.csdn.net/wangdd_199326/article/details/76180514 fork Linux多进程 ...
- fork函数详解
一.fork入门知识 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同, ...
- 你好,C++(27)在一个函数内部调用它自己本身 5.1.5 函数的递归调用
5.1.5 函数的递归调用 在函数调用中,通常我们都是在一个函数中调用另外一个函数,以此来完成其中的某部分功能.例如,我们在main()主函数中调用PowerSum()函数来计算两个数的平方和,而在P ...
- UNIX环境高级编程学习笔记(十)为何 fork 函数会有两个不同的返回值【转】
转自:http://blog.csdn.net/fool_duck/article/details/46917377 以下是基于 linux 0.11 内核的说明. 在init/main.c第138行 ...
- 关于fork( )函数父子进程返回值的问题
fork()是linux的系统调用函数sys_fork()的提供给用户的接口函数,fork()函数会实现对中断int 0x80的调用过程并把调用结果返回给用户程序. fork()的函数定义是在init ...
- 每次调用fork()函数之后,父线程和创建出的子线程都是从fork()后开始执行
Linux下多少个"-"将被打印: 1 2 3 4 5 6 7 8 int main(void){ int i; for(i=0;i<4;i++){ fork() ...
- python学习笔记10(函数一): 函数使用、调用、返回值
一.函数的定义 在某些编程语言当中,函数声明和函数定义是区分开的(在这些编程语言当中函数声明和函数定义可以出现在不同的文件中,比如C语言),但是在Python中,函数声明和函数定义是视为一体的.在Py ...
- 利用jQuery扩展接口为jQuery框架定义了两个自定义函数,然后调用这两个函数
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
随机推荐
- HDU4405(期望dp)
标准期望套路,很水.读题看好是到n就可以停止了. ; int n, m; db dp[maxn]; map<int, int> mp; int main() { while (~scanf ...
- js中对象的理解
JS中对象是可变的控件集合,对象的内容是可以更改的,可以为它添加任意属性或删除,而基本数据类型虽然拥有方法,但它们的值是不可变的,之所以它们拥有方法,是因为当它们调用方法是,后台会自动创建一个相映包装 ...
- tera term超级终端
一款Window上的虚拟终端工具,它同时支持串口连接和网络连接,而对于网络连接它支持Telnet和SSH协议.最关键的是Tera Term支持自己的脚本语言,即TTL(Tera Term Langua ...
- Rasheda And The Zeriba Gym - 100283A 计算几何
http://codeforces.com/gym/100283/problem/A 考虑到多边形是不稳定的,是可以变来变去的. 那么总是可以把每个点放到圆上. 所以只需要判断圆心角是不是小于等于36 ...
- javascript要点(上)
立即执行函数 即Immediately Invoked Function Expression (IIFE),正如它的名字,就是创建函数的同时立即执行.它没有绑定任何事件,也无需等待任何异步操作: ( ...
- Apache的多处理模块MPM
本博文主要参数 Apache 2.2文档以及Apache模块开发指南 Apache的整个运行可以分为两个阶段:启动阶段和运行阶段. 在启动阶段时,它以ROOT特权来启动,进行解析配置文件(一般就是ht ...
- HTML 5的革新——语义化标签(一)HTML 5的革新——语义化标签(二)
HTML 5的革新之一:语义化标签一节元素标签. 在HTML 5出来之前,我们用div来表示页面章节,但是这些div都没有实际意义.(即使我们用css样式的id和class形容这块内容的意义).这些标 ...
- log4j日志工具类
/** * log4j日志Util */public class LogUtil { private static Logger logger=null; static{ StackTraceElem ...
- 6、旋转数组的最小位置------------>剑指offer系列
题目 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转, ...
- 修改本地dns域名对应的 ip
C:\Windows\System32\drivers\etc 打开 hosts 文件 在浏览器 访问 http://a.com,就相当于访问 127.0.0.2 这个ip了