在Linux中,fork函数的功能就是在一个进程中创建一个新的进程,当前调用fork函数的进程就是产生的新进程的父进程,新进程在以下也称为子进程。在新进程生成之后就会在系统中开始执行。

函数原型:pid_t fork(void); 其中pid_t 是一个long。

pid_t fork(void); 

  在父进程中,返回值是子进程的进程ID,而在子进程中,返回值则是0,所以可以通过判断fork函数的返回值来判断当前执行的是父进程还是子进程。

  创建之后的子进程与父进程执行相同的程序段,但是拥有不同的堆栈段以及数据段,但是子进程中堆栈段和数据段都是父进程的完全复制,直到调用exec()函数簇让子进程去执行的新的代码,子进程就完全拥有了属于自己的代码段、堆栈段和数据段。

  在这个过程中,期初的Linux系统,确实是将父进程的所有内存进行复制产生新的进程映像,但太浪费内存了,所以现在并不会直接复制父进程的所有内存,而是子进程与父进程共享代码段,子进程的一系列进程级列表都指向父进程的页表,在exec()函数调用之后,再对子进程的页表进行相应的调整,这个操作就用到了写时复制技术(copy-on-write),也就是从这一刻起,子进程开始独立地执行新的代码段。

pid_t childPid;
switch(childPid = fork()) {
case -:
//error
break; case :
//child process
break; default:
//father process comes here after fork()
}

  当进程创建失败时,fork()的返回值存放在errno中,当其为EAGAIN是,原因是进程的数目超过了当前允许创建的进程数量的最大值;当其为ENOMEM,表示内存不足,无法配置核心所需的数据结构空间。

在Linux中,与fork()功能类似还有一个函数vfork(),这个函数也是创建一个进程,但是与fork()有一些不同,vfork()的设计理念是在创建新进程之后,阻塞父进程,用子进程直接执行新的代码,并且使用父进程的内存,直到子进程执行完毕返回,父进程才会继续执行。在早期的Linux中vfork()比fork()更高效,因为vfork()不会只会复制父进程的部分内容,但是在现在的Linux系统中,由于写时复制技术,fork()的效率大大提高,甚至和fork()不相上下,所以尽量避免使用vfork()函数。而且由于vfork()创建的进程与父进程共享内存,极有可能出现各种未知的错误,这也是避免使用vfork()的重要原因。

Linux编程之fork函数的更多相关文章

  1. 深入浅出--UNIX多进程编程之fork()函数

    0前言 上周都在看都在学习unix环境高级编程的第八章--进程控制.也就是这一章中.让我理解了unix中一些进程的原理.以下我就主要依照进程中最重要的三个函数来进行解说.让大家通过阅读这一篇文章彻底明 ...

  2. Linux进程之Fork函数

    Fork()函数 1.所需头文件: #include <unistd.h> #include<sys/types.h> 2.函数定义 pid_t fork( void ); p ...

  3. linux编程之pipe()函数

    管道是一种把两个进程之间的标准输入和标准输出连接起来的机制,从而提供一种让多个进程间通信的方法,当进程创建管道时,每次 都需要提供两个文件描述符来操作管道.其中一个对管道进行写操作,另一个对管道进行读 ...

  4. linux编程之main()函数启动过程【转】

    转自:http://blog.csdn.net/gary_ygl/article/details/8506007 1 最简单的程序  1)编辑helloworld程序,$vim helloworld. ...

  5. Linux编程之ICMP洪水攻击

    我的上一篇文章<Linux编程之PING的实现>里使用ICMP协议实现了PING的程序,ICMP除了实现这么一个PING程序,还有哪些不为人知或者好玩的用途?这里我将介绍ICMP另一个很有 ...

  6. Windows编程之connect函数研究

    写在前面:本博客为本人原创,严禁任何形式的转载!本博客只允许放在博客园(.cnblogs.com),如果您在其他网站看到这篇博文,请通过下面这个唯一的合法链接转到原文! 本博客全网唯一合法URL:ht ...

  7. Linux下多进程编程之exec函数语法及使用实例

    exec函数族 1)exec函数族说明 fork()函数用于创建一个子进程,该子进程几乎复制了父进程的全部内容,但是,这个新创建的进程如何执行呢?exec函数族就提供了一个在进程中启动另一个程序执行的 ...

  8. linux进程之fork 和 exec函数

    ---恢复内容开始--- fork函数 该函数是unix中派生新进程的唯一方法. #include <unistd.h> pid_t   fork(void); 返回: (调用它一次, 它 ...

  9. Linux C 中 fork() 函数详解

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

随机推荐

  1. ucos中需要注意的全局变量

    首先聊一聊全局变量: 在慕课上学习浙大老师的C语言课程的时候,翁恺老师一直在强调在程序中我们要避免使用全局变量,C语言的程序员(尤其像我这样的野生程序员)为了方便,经常会不顾这个编码规范.全局变量有一 ...

  2. 定点CORDIC算法求所有三角函数及向量模的原理分析、硬件实现(FPGA)

    一.CORDIC算法 CORDIC(Coordinate Rotation DIgital Computer)是一种通过迭代对多种数学函数求值的方法,它可以对三角函数.双曲函数和平面旋转问题进行求解. ...

  3. AttributeError: 'LoginForm' object has no attribute 'is_bound' , object has no attribute 'is_bound'

    'LoginForm' object has no attribute 'is_bound' 可能原因: 啥子问题?? 都是 jquery.js 文件.....

  4. gitlab-ci.xml:script config should be a string or an array of strings

    The following command in a job script: STATUS_ID=$(grep -Eo "Status Code [0-9]+: Done" som ...

  5. vue根据路由变换,切换导航栏样式

    <ul> <li> <router-link :to="{name: 'home'}" class="active_item" e ...

  6. python—列表生成式

    #原始写法 l=[] for i in range(1,11): l.append(str(i).zfill(2)) print(l) #结果:['01', '02', '03', '04', '05 ...

  7. rancher的Ingress的文件大小上传限制配置

    添加注释 nginx.ingress.kubernetes.io/proxy-body-size

  8. 1.为什么使用spring boot

    最近2年spring cloud微服务比较流行,Spring Cloud基于SpringBoot,为微服务体系开发中的架构问题提供了一整套的解决方案, 本文总结一下为什么要使用Spring boot, ...

  9. 进军的socket

    在学socket有时候我们会遇到这种问题: 解决方法一: 在服务端中加入:severTCP.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) ...

  10. angular2监听页面大小变化

    一.现象 全屏页面中的图表,在很多的时候需要 resize 一把,以适应页面的大小变化 二.解决 1.引入 : import { Observable } from 'rxjs'; 2.使用(在ngO ...