1、定义
#include <unistd.h>
#include<sys/types.h>
pid_t fork( void );

pid_t 是一个宏定义,其实质是int,被定义在#include<sys/types.h>中

返回值:若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-1

2、函数说明:

一个现有进程可以调用fork函数创建一个新进程。由fork创建的新进程被称为子进程(child process)。fork函数被调用一次但返回两次。两次返回的唯一区别是子进程中返回0值而父进程中返回子进程ID。

子进程是父进程的副本,它将获得父进程数据空间、堆、栈等资源的副本。注意,子进程持有的是上述存储空间的“副本”,这意味着父子进程间不共享这些存储空间。File locks and pending signals are not inherited. 【3】

If the call to fork() is executed successfully, Unix will

① make two identical copies of address spaces, one for the parent and the other for the child.

② Both processes will start their execution at the next statement following the fork() call.

3、为什么fork会返回两次?

由于在复制时复制了父进程的堆栈段,所以两个进程都停留在fork函数中,等待返回。因为fork函数会返回两次,一次是在父进程中返回,另一次是在子进程中返回,这两次的返回值是不一样的。

After a new child process is created, both processes will execute the next instruction following the fork() system call.

调用fork之后,代码有两份,都从fork函数中返回。

Please note that Unix will make an exact copy of the parent's address space and give it to the child. Therefore, the parent and child processes have separate address spaces.


实例代码1:

#include<sys/types.h>
#include<unistd.h>
#include<stdio.h>

int main(int argc,char**argv)
{
    int pid=fork();
    if(pid == -1)
    {
        print("error!");
    }
    else if(pid == 0)
    {
        print("This is the child process!");
    }
    else
    {
        print("This is the parent process! child process id = %d", pid);
    }
    return 0;
}

示例代码2:

#include  <stdio.h>
#include  <string.h>
#include  <sys/types.h>
#include <unistd.h>

#define   MAX_COUNT  200
#define   BUF_SIZE   100

void  main(void)
{
     pid_t  pid;
     int    i;
     char   buf[BUF_SIZE];

     fork();
     pid = getpid();
     for (i = 1; i <= MAX_COUNT; i++) {
          sprintf(buf, "This line is from pid %d, value = %d\n", pid, i);
          write(1, buf, strlen(buf));
     }
}

为什么用write,而不用printf呢?because printf() is "buffered," meaning printf() will group the output of a process together,这样,会把子进程和父进程的输出混起来。所以用use the "unbuffered" write。


示例代码3:

#include  <stdio.h>
#include  <sys/types.h>

#define   MAX_COUNT  200

void  ChildProcess(void);                /* child process prototype  */
void  ParentProcess(void);               /* parent process prototype */

int  main(void)
{
     pid_t  pid;

     pid = fork();
     if (pid == 0)
          ChildProcess();
     else
          ParentProcess();
    return 0;
}

void  ChildProcess(void)
{
     int   i;

     for (i = 1; i <= MAX_COUNT; i++)
          printf("   This line is from child, value = %d\n", i);
     printf("   *** Child process is done ***\n");
}

void  ParentProcess(void)
{
     int   i;

     for (i = 1; i <= MAX_COUNT; i++)
          printf("This line is from parent, value = %d\n", i);
     printf("*** Parent is done ***\n");
}

4、Error Codes

出错返回错误信息如下:

EAGAIN :达到进程数上限.

ENOMEM :没有足够空间给一个新进程分配.

fork()系统在Linux中的返回值是没有NULL的.

深入解析Linux中的fork函数的更多相关文章

  1. [fork]Linux中的fork函数详解

    ---------------------------------------------------------------------------------------------------- ...

  2. Unix/Linux中的fork函数

    fork函数介绍 一个现有进程可以调用fork函数创建一个新进程.该函数定义如下: #include <unistd.h> pid_t fork(void); // 返回:若成功则在子进程 ...

  3. linux中的fork()函数以及标准I/O缓冲

    1. fork()创建的新进程成为子进程.一次调用,两次返回,子进程的返回值是0,而父进程的返回值是新子进程的进程ID,如果出现错误,fork返回一个负值. 2. 可以通过fork返回的值来判断当前进 ...

  4. linux中的fork函数的基本用法

    代码: #include <iostream> #include <string> #include <cstdio> #include <unistd.h& ...

  5. Linux编程之fork函数

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

  6. 【Linux 进程】fork函数详解

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

  7. 解析Linux中的VFS文件系统机制

    转载:原文地址https://www.ibm.com/developerworks/cn/linux/l-vfs/ 1. 摘要 本文阐述 Linux 中的文件系统部分,源代码来自基于 IA32 的 2 ...

  8. 浅析linux中的fork、vfork和clone

    各种大神的混合,做个笔记. http://blog.sina.com.cn/s/blog_7598036901019fcg.html http://blog.csdn.net/kennyrose/ar ...

  9. Linux 环境下 fork 函数和 exec 函数族的使用

    前言 接触 Linux 已经有几个月了,以前在网上看各路大神均表示 Windows 是最烂的开发平台,我总是不以为然,但是经过这段时间琢磨,确实觉得 Linux 开发给我带来不少的便利.下面总结一下学 ...

随机推荐

  1. Check the string CodeForces - 960A

    A has a string consisting of some number of lowercase English letters 'a'. He gives it to his friend ...

  2. Docker其它安全特性

    除了能力机制之外,还可以利用一些现有的安全机制来增强使用 Docker 的安全性,例如 TOMOYO, AppArmor, SELinux, GRSEC 等. Docker 当前默认只启用了能力机制. ...

  3. Tomcat中的c3p0数据库连接池的释放

    一个项目通过c3p0获得连接池,相关代码如下: public class JdbcUtil { // 连接池的核心类 private static ComboPooledDataSource data ...

  4. [mysql]创建数据库并指定编码

    现在用orm比较多,很多mysql表啊都不用自己创建,但是数据库还是要自己创建,记录下sql, 备忘. CREATE DATABASE `mydb` CHARACTER SET utf8 COLLAT ...

  5. Java进阶(四十二)Java中多线程使用匿名内部类的方式进行创建3种方式

    Java中多线程使用匿名内部类的方式进行创建3种方式 package cn.edu.ujn.demo; // 匿名内部类的格式: public class ThreadDemo { public st ...

  6. The type org.apache.http.HttpResponse cannot be resolved. It is indirectly referenced from required

    在Android 6.0(API 23)中,Google已经移除了移除了Apache HttpClient相关的类.HttpResponse类.缺失jar包使用HttpResponse等会报错: Th ...

  7. 剑指Offer——银行网申内容模版

    剑指Offer--银行网申内容模版 年获得"优秀共青团员"称号 2013.12 科技标兵 2013.10 三好学生 2013.10 "三下乡"优秀学生 2013 ...

  8. Android View框架总结(二)View焦点

    请尊重分享成果,转载请注明出处: http://blog.csdn.net/hejjunlin/article/details/52263256 前言:View框架写到第六篇,发现前面第二篇竟然没有, ...

  9. 2.4、Android Studio使用主题编辑器设计主题

    Android Studio包含一个叫主题编辑器的可视的助手,可以提供以下功能: 1. 创建和更改你的app主题 2. 为不同的资源适应主题 3. 普通的UI颜色更改的实时显示 主题编辑器 这一节描述 ...

  10. 关于tomcat中Servlet对象池

    Servlet在不实现SingleThreadModel的情况下运行时是以单个实例模式,如下图,这种情况下,Wrapper容器只会通过反射实例化一个Servlet对象,对应此Servlet的所有客户端 ...