Linux C编程--fork()详解
以下给出说明:
fork函数
#include <sys/types.h>
#include <unistd.h> pid_t fork(void);
fork调用失败则返回-1,调用成功的返回值见下面的解释。我们通过一个例子来理解fork是怎样创建新进程的。
这个程序的运行过程如下图所示。

父进程初始化。
父进程调用
fork,这是一个系统调用,因此进入内核。内核根据父进程复制出一个子进程,父进程和子进程的PCB信息相同,用户态代码和数据也相同。因此,子进程现在的状态看起来和父进程一样,做完了初始化,刚调用了
fork进入内核,还没有从内核返回。现在有两个一模一样的进程看起来都调用了
fork进入内核等待从内核返回(实际上fork只调用了一次),此外系统中还有很多别的进程也等待从内核返回。是父进程先返回还是子进程先返回,还是这两个进程都等待,先去调度执行别的进程,这都不一定,取决于内核的调度算法。如果某个时刻父进程被调度执行了,从内核返回后就从
fork函数返回,保存在变量pid中的返回值是子进程的id,是一个大于0的整数,因此执下面的else分支,然后执行for循环,打印"This is the parent\n"三次之后终止。如果某个时刻子进程被调度执行了,从内核返回后就从
fork函数返回,保存在变量pid中的返回值是0,因此执行下面的if (pid == 0)分支,然后执行for循环,打印"This is the child\n"六次之后终止。fork调用把父进程的数据复制一份给子进程,但此后二者互不影响,在这个例子中,fork调用之后父进程和子进程的变量message和n被赋予不同的值,互不影响。父进程每打印一条消息就睡眠1秒,这时内核调度别的进程执行,在1秒这么长的间隙里(对于计算机来说1秒很长了)子进程很有可能被调度到。同样地,子进程每打印一条消息就睡眠1秒,在这1秒期间父进程也很有可能被调度到。所以程序运行的结果基本上是父子进程交替打印,但这也不是一定的,取决于系统中其它进程的运行情况和内核的调度算法,如果系统中其它进程非常繁忙则有可能观察到不同的结果。另外,读者也可以把
sleep(1);去掉看程序的运行结果如何。这个程序是在Shell下运行的,因此Shell进程是父进程的父进程。父进程运行时Shell进程处于等待状态,当父进程终止时Shell进程认为命令执行结束了,于是打印Shell提示符,而事实上子进程这时还没结束,所以子进程的消息打印到了Shell提示符后面。最后光标停在
This is the child的下一行,这时用户仍然可以敲命令,即使命令不是紧跟在提示符后面,Shell也能正确读取。
fork函数的特点概括起来就是“调用一次,返回两次”,在父进程中调用一次,在父进程和子进程中各返回一次。从上图可以看出,一开始是一个控制流程,调用fork之后发生了分叉,变成两个控制流程,这也就是“fork”(分叉)这个名字的由来了。子进程中fork的返回值是0,而父进程中fork的返回值则是子进程的id(从根本上说fork是从内核返回的,内核自有办法让父进程和子进程返回不同的值),这样当fork函数返回后,程序员可以根据返回值的不同让父进程和子进程执行不同的代码。
fork的返回值这样规定是有道理的。fork在子进程中返回0,子进程仍可以调用getpid函数得到自己的进程id,也可以调用getppid函数得到父进程的id。在父进程中用getpid可以得到自己的进程id,然而要想得到子进程的id,只有将fork的返回值记录下来,别无它法。
fork的另一个特性是所有由父进程打开的描述符都被复制到子进程中。父、子进程中相同编号的文件描述符在内核中指向同一个file结构体,也就是说,file结构体的引用计数要增加。
Linux C编程--fork()详解的更多相关文章
- Linux Shell 编程基础详解——吐血整理,墙裂推荐!
第一部分:Linux Shell 简介 Shell 是一个用 C 语言编写的程序,它是用户使用 Linux 的桥梁.Shell 既是一种命令语言,又是一种程序设计语言. Shell 是指一种应用程序, ...
- Java网络编程和NIO详解6:Linux epoll实现原理详解
Java网络编程和NIO详解6:Linux epoll实现原理详解 本系列文章首发于我的个人博客:https://h2pl.github.io/ 欢迎阅览我的CSDN专栏:Java网络编程和NIO h ...
- linux --> fork()详解
fork()详解 一个进程,包括代码.数据和分配给进程的资源.fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个 ...
- Linux惊群效应详解
Linux惊群效应详解(最详细的了吧) linux惊群效应 详细的介绍什么是惊群,惊群在线程和进程中的具体表现,惊群的系统消耗和惊群的处理方法. 1.惊群效应是什么? 惊群效应也有人 ...
- 嵌入式Linux应用程序开发详解------(创建守护进程)
嵌入式Linux应用程序开发详解 华清远见 本文只是阅读文摘. 创建一个守护进程的步骤: 1.创建一个子进程,然后退出父进程: 2.在子进程中使用创建新会话---setsid(): 3.改变当前工作目 ...
- Linux I/O 重定向详解及应用实例
Linux I/O 重定向详解及应用实例 简解 > 输出 < 输入 >> 追加 & [> | < | >>]之前:输入输出; ls /dev & ...
- linux的system () 函数详解
linux的system () 函数详解 system(执行shell 命令)相关函数 fork,execve,waitpid,popen表头文件 #i nclud ...
- Linux主要shell命令详解(上)
[摘自网络] kill -9 -1即实现用kill命令退出系统 Linux主要shell命令详解 [上篇] shell是用户和Linux操作系统之间的接口.Linux中有多种shell,其中缺省使用的 ...
- Linux下ps命令详解 Linux下ps命令的详细使用方法
http://www.jb51.net/LINUXjishu/56578.html Linux下的ps命令比较常用 Linux下ps命令详解Linux上进程有5种状态:1. 运行(正在运行或在运行队列 ...
随机推荐
- 从最简单的HelloWorld理解MVP模式
版权声明:本文为博主原创文章,转载请注明出处:http://www.cnblogs.com/joy99/p/6116855.html 大多数编程语言相关的学习书籍,都会以hello,world这个典型 ...
- ASP.NET forms凭据设置和跳转的几种方法
string user = "userName"; //默认的第1种,超时时间是在web.cofig中forms设置的timeout,单位是分钟,生成的cookie和凭证超时时间一 ...
- ListCtrl控件的使用
list contrl控件的使用 .建立基于对话框的应用程序,布置界面,设置属性. 注意添加的是listctrl控件,不是listbox控件,在控件工具箱的倒数第五行list control控件. 属 ...
- <Android>关于EditText中setInputType和setSingleLine的冲突
近期自己开发了一个带有删除button的EditText,一方面须要设置为SingleLine,还有一方面又须要设置输入类型,起先在xml文件里设置了android:inputType类型,在自己定义 ...
- Android腾讯微博开发之随机字符串与签名实现
Android腾讯微博开发入门之随机字符串与签名实现 直接上代码 1.Utils类,包括签名和随机字符串 import java.util.Random; import javax.cry ...
- [ES6] 19. for ... of
In ES5, we have for ... in: var phones = ["iPhone", "Nexus", "Nokia"]; ...
- iOS开发——图形编程OC篇&粘性动画以及果冻效果
粘性动画以及果冻效果 在最近做个一个自定义PageControl——KYAnimatedPageControl中,我实现了CALayer的形变动画以及CALayer的弹性动画,效果先过目: 先做个提纲 ...
- PhpStorm, XDebug, and DBGp Proxy
phpstorm 利用 xdebug.dbgp-proxy配置远程调试 1.单客户机远程调试 a.安装xdebug库文件(windows:php_xdebug.dll;linux:php_xdebug ...
- C++之运算符重载(1)
在前一节中曾提到过,C++中运行时的多态性主要是通过虚函数来实现的,而编译时的多态性是由函数重载和运算符重载来实现的.这一系列我将主要讲解C++中有关运算符重载方面的内容.在每一个系列讲解之前,都会有 ...
- Android基本控件之GridView
我们在使用手机的过程中,会看到一些图片配上文字的一些情况,今天我们就来介绍一下安卓控件的GridView GridView组件用来以网格方式排列视图,与矩阵类似,当屏幕上有很多元素(文字.图片或其他元 ...