在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. Game Engine Architecture 8

    [Game Engine Architecture 8] 1.Differences across Operating Systems • UNIX uses a forward slash (/) ...

  2. Java框架spring 学习笔记(十九):事务管理(注解管理)

    注解管理的方式要比xml配置方式要简单很多 只需在配置文件中添加事务注解 <?xml version="1.0" encoding="UTF-8"?> ...

  3. 常用vi命令

    i  在当前光标处插入字符,并进入编辑模式 o 在当前光标插入下一行 x 从当前光标处向后删除一个字符. dd 删除当前光标处所在行 :q! 强制退出不保存 :q 退出(文本有改动则警告) :w 保存 ...

  4. 下拉js的实现

    这个JS是出自一个浴室柜网站 $(document).ready(function(){ $(".side_nav_3").hover(function() { $(this).f ...

  5. LinkedStack

    public class LinkedStack<T> { private static class Node<U>{ U item; Node<U>next; N ...

  6. 【c# 数据库】对数据库进行增删查改

    1.DataGridView链接数据库 2.链接数据库 using System.Data.SqlClient; SqlConnection con = null; //创建SqlConnection ...

  7. HTTPClient to use http/https protocol to send request

    使用了spring boot, gradle, commons-httpcomponent3. 目前httpclient 已经有了版本4. https://github.com/lvfe/httpCl ...

  8. 52-2018 蓝桥杯省赛 B 组模拟赛(一)java

    最近蒜头君喜欢上了U型数字,所谓U型数字,就是这个数字的每一位先严格单调递减,后严格单调递增.比如 212212 就是一个U型数字,但是 333333, 9898, 567567, 313133131 ...

  9. android 7.0+ FileProvider 访问隐私文件 相册、相机、安装应用的适配

    从 Android 7.0 开始,Android SDK 中的 StrictMode 策略禁止开发人员在应用外部公开 file:// URI.具体表现为,当我们在应用中使用包含 file:// URI ...

  10. 7B - 今年暑假不AC

    “今年暑假不AC?” “是的.” “那你干什么呢?” “看世界杯呀,笨蛋!” “@#$%^&*%...” 确实如此,世界杯来了,球迷的节日也来了,估计很多ACMer也会抛开电脑,奔向电视了.  ...