原文来自于:http://baike.baidu.com/view/1952900.htm?fr=aladdin

fork编辑

叉子\分岔\岔口\复刻,西方人吃饭用的东西,经常用作刀和叉。
计算机程序设计中的分叉函数。返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程标记;否则,出错返回-1。
fork函数将运行着的程序分成2个(几乎)完全一样的进程,每个进程都启动一个从代码的同一位置开始执行的线程。这两个进程中的线程继续执行,就像是两个用户同时启动了改应用程序的两个副本。
 

1分叉函数编辑

头文件

1
2
#include<unistd.h>/*#包含<unistd.h>*/
#include<sys/types.h>/*#包含<sys/types.h>*/

函数原型

pid_t forkvoid);
(pid_t 是一个宏定义,其实质是int 被定义在#include<sys/types.h>中)
返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1

函数说明

一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。
子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。
UNIX将复制父进程地址空间内容给子进程,因此,子进程有了独立的地址空间。在不同的UNIX (Like)系统下,我们无法确定fork之后是子进程先运行还是父进程先运行,这依赖于系统的实现。所以在移植代码的时候我们不应该对此作出任何的假设。
为什么fork会返回两次?
由于在复制时复制了父进程堆栈段,所以两个进程都停留在fork函数中,等待返回。因此fork函数会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。过程如下图。
 
  1. fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
      在父进程中,fork返回新创建子进程的进程ID;
  2. 在子进程中,fork返回0;
  3. 如果出现错误,fork返回一个负值。
在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。
引用一位网友的话来解释fork函数返回的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fork函数返回的值指向子进程的进程id, 因为子进程没有子进程,所以其fork函数返回的值为0.
调用fork之后,数据、堆栈有两份,代码仍然为一份但是这个代码段成为两个进程的共享代码段都从fork函数中返回,箭头表示各自的执行处。当父子进程有一个想要修改数据或者堆栈时,两个进程真正分裂。
示例代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<sys/types.h>//对于此程序而言此头文件types.h用不到
#include<unistd.h>
#include<stdio.h>
#include<stdlib.h>
 
intmain(intargc,char*argv[])/*整数类型主函数*/
{
pid_tpid=fork();/*传递参数*/
if(pid<0)/*如果(进程标记<0)*/
{
fprintf(stderr,"错误!");
}
elseif(pid==0)/*否则如果(进程标记==0)*/
{
printf("百度百科:这是子进程!");
exit(0);
}
else/*否则*/{
printf("百度百科:这是父进程!子进程的进程标记为=%d",pid);
}
//可能需要时候wait或waitpid函数等待子进程的结束并获取结束状态
exit(0);
}
注意!样例代码仅供参考,样例代码存在着父进程在子进程结束前结束的可能性。必要的时候可以使用wait或 waitpid函数让父进程等待子进程的结束并获取子进程的返回状态。
fork()在Linux系统中的返回值是没有NULL的.
Error Codes
出错返回错误信息如下:
EAGAIN
达到进程数上限.
ENOMEM
没有足够空间给一个新进程分配.
fork函数的特点概括起来就是“调用一次,返回两次”,在父进程中调用一次,在父进程和子进程中各返回一次。
fork的另一个特性是所有由父进程打开的描述符都被复制到子进程中。父、子进程中相同编号的文件描述符内核中指向同一个file结构体,也就是说,file结构体的引用计数要增加。
[1] 

2中文翻译编辑

叉子\分岔\岔口\复刻,西方人吃饭用的东西,经常用作刀和叉。
 
参考资料
  • 1.  Robert Love .Linux Kernel Development(Third Edition) :机械工业出版社 ,2011.6 .

转:fork的解释的更多相关文章

  1. mongodb集群+分片部署(二)

    机器:10.165.38.68    10.165.38.72 部署包:mongodb-linux-x86_64-rhel55-3.0.2.tgz(百度云盘下载地址:http://pan.baidu. ...

  2. mongodb部署单节点(一)

    部署包:mongodb-linux-x86_64-rhel55-3.0.2.tgz(百度云盘下载地址:http://pan.baidu.com/s/1jIQAGlw 密码:l7pf) 第一步:上传该文 ...

  3. 【夯实PHP基础】PHP多进程-- pcntl_fork实现

    本文地址 参考文档 分享提纲: 1. 概述 2.安装(只支持Linux) 3. 代码实验多进程pcntl_fork 4. 具体解释 1. 概述 PHP有个pcntl_fork的函数可以实现多进程,但要 ...

  4. python3之线程与进程

    1.CPU运行原理 我们都知道CPU的根本任务就是执行指令,对计算机来说最终都是一串由“0”和“1”组成的序列.CPU从逻辑上可以划分成3个模块,分别是控制单元.运算单元和存储单元,这三部分由CPU内 ...

  5. CentOS7.5安装MongoDB4.0与CRUD基本操作

    一 MongoDB简介 MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数 ...

  6. 【APUE】Chapter8 Process Control

    这章的内容比较多.按照小节序号来组织笔记的结构:再结合函数的示例带代码标注出来需要注意的地方. 下面的内容只是个人看书时思考内容的总结,并不能代替看书(毕竟APUE是一本大多数人公认的UNIX圣经). ...

  7. CentOS系统环境下安装MongoDB

    (1)进入MongoDB下载中心:http://www.mongodb.org/downloads We recommend using these binary distributions (官方推 ...

  8. Shell 03 for while case 函数 中断及退出

    一.for循环 1.脚本1,通过循环批量显示5个hello world    ( in 1 2 3 4 5 ) 2.脚本2,通过循环批量显示10个hello world   ( in {1..10} ...

  9. mongodb集群搭建过程记录

    mongodb集群搭建花费比较长的时间,在此记录下过程,方便以后使用 一 软件环境 系统:ubuntu 18.04,mongodb 社区版4.2 https://docs.mongodb.com/ma ...

随机推荐

  1. bzoj2132: 圈地计划

    要分成两坨对吧.. 所以显然最小割 但是不兹辞啊.. 最小割是最小的啊 求最大费用怎么玩啊 那咱们就把所有费用都加起来,减掉一个最小的呗 但是两个属于不同集合的点贡献的价值是负的啊 网络流怎么跑负的啊 ...

  2. 解决IE6,IE7不能隐藏绝对定位溢出的内容

    令人蛋疼的IE,IE6/IE7下父元素有相对/绝对定位时,子元素在IE6和IE7下overflow:hidden;失效. 情况一:(在parent上增加position:relative) <s ...

  3. 移植QT到ZedBoard(制作运行库镜像) 交叉编译 分类: ubuntu shell ZedBoard OpenCV 2014-11-08 18:49 219人阅读 评论(0) 收藏

    制作运行库 由于ubuntu的Qt运行库在/usr/local/Trolltech/Qt-4.7.3/下,由makefile可以看到引用运行库是 INCPATH = -I/usr//mkspecs/d ...

  4. [io PWA] Great libraries and tools for great Progressive Web Apps

    sw-toolbox: Github It provides a cononical implementation of all the runtime caching strategies that ...

  5. SQL Server未找到或无法訪问server问题解决

    问题信息:"在与 SQL Server 建立连接时出现与网络相关的或特定于实例的错误.未找到或无法訪问服务器.请验证实例名称是否正确而且 SQL Server 已配置为同意远程连接. (pr ...

  6. MySQL内存体系架构及参数总结 ---图解

    http://www.cnblogs.com/kissdb/p/4009614.html 内存结构: Mysql 内存分配规则是:用多少给多少,最高到配置的值,不是立即分配 图只做大概参考 全局缓存包 ...

  7. iOS--日历事件的获取和添加

    日历添加事件 EKEventStore* eventStore = [[EKEventStore alloc] init];//获取日历类 EKEvent *event = [EKEvent even ...

  8. windows 环境下mysql 如何修改root密码

    windows 环境下mysql 如何修改root密码 以windows为例: 无法开启服务,将mysql更目录下的data文件夹清空,然后调用 mysqld --initialize 开启mysql ...

  9. 单例模式,多种实现方式JAVA

    转载请注明出处:http://cantellow.iteye.com/blog/838473 第一种(懒汉,线程不安全): public class Singleton { private stati ...

  10. SQL存储过程传入字段名查询.

    根据字段名和对应的值查询. (正确代码):目前发现,需要"分组,排序"等才能解决,如"order by","group by"等. SQL代 ...