fork()函数详解

2023-11-18

一个进程,包括代码、数据和分配给进程的资源。fork()函数通过系统调用创建一个与原来进程几乎完全相同的进程,也就是两个进程可以做完全相同的事,但如果初始参数或者传入的变量不同,两个进程也可以做不同的事。
一个进程调用fork()函数后,系统先给新的进程分配资源,例如存储数据和代码的空间。然后把原来的进程的所有值都复制到新的新进程中,只有少数值与原来的进程的值不同。相当于克隆了一个自己。

 我们来看一个例子:

点击(此处)折叠或打开

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

/*
* @brief main For the understanding of the fork()
*
* @param argc
* @param argv[]
*
* @return 在父进程中返回子进程的进程号;在子进程中返回0*/
int main(int argc, char *argv[])
{
    pid_t pid; 
    int cnt = 0;

    pid = fork();

    if (pid == -1) {
        perror("fork error");
        exit(1);
    } else if (pid == 0) {
        printf("The returned value is %d\nIn child process!!\nMy PID is %d\n",
        pid, getpid());
        cnt++;
    } else {
        printf("The returned value is %d\nIn father process!!\nMy PID is %d\n",
        pid, getpid());
        cnt++;
    }
    printf("cnt = %d\n", cnt);

    return 0;
}
     运行结果是:
     The returned value is 20473
     In father process!!
     My PID is 20472
     cnt = 1
     The returned value is 0
     In child process!!
     My PID is 20473
     cnt = 1

    在语句pid=fork()之前,只有一个进程在执行这段代码,但在这条语句之后,就变成两个进程在执行了,这两个进程的几乎完全相同,将要执行的下一条语句都是if(pid == -1)……
    为什么两个进程的pid不同呢,这与fork函数的特性有关。fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
    1)在父进程中,fork返回新创建子进程的进程ID;
    2)在子进程中,fork返回03)如果出现错误,fork返回-1;

    在fork函数执行完毕后,如果创建新进程成功,则出现两个进程,一个是子进程,一个是父进程。在子进程中,fork函数返回0,在父进程中,fork返回新创建子进程的进程ID。我们可以通过fork返回的值来判断当前进程是子进程还是父进程。

    pid的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的pid(p 意味point)指向子进程的进程id, 因为子进程没有子进程,所以其pid为0.

    fork出错可能有两种原因:
    1)当前的进程数已经达到了系统规定的上限,这时errno的值被设置为EAGAIN。
    2)系统内存不足,这时errno的值被设置为ENOMEM。
    创建新进程成功后,系统中出现两个基本完全相同的进程,子进程从父进程处继承了整个进程的地址空间,包括进程上下文、代码段、进程堆栈、内存信息、打开的文件描述符、信号控制设定、进程优先级、进程组号、当前工作目录、根目录、资源限制和控制终端, 父子进程不共享这些存储空间部分,父子进程共享正文段。这两个进程执行没有固定的先后顺序,哪个进程先执行要看系统的进程调度策略。

    每个进程都有一个独特(互不相同)的进程标识符(process ID),可以通过getpid()函数获得,还有一个记录父进程pid的变量,可以通过getppid()函数获得变量的值。

  有人说两个进程的内容完全一样啊,怎么打印的结果不一样啊,那是因为判断条件的原因,上面列举的只是进程的代码和指令,还有变量啊。

    执行完fork后,进程1的变量为cnt=0,pid != 0(父进程)。进程2的变量为count=0,pid=0(子进程),这两个进程的变量都是独立的,存在不同的地址中,不是共用的,这点要注意。可以说,我们就是通过pid来识别和操作父子进程的。
    还有人可能疑惑为什么不是从#include处开始复制代码的,这是因为fork是把进程当前的情况拷贝一份,执行fork时,进程已经执行完了int cnt=0;fork只拷贝下一个要执行的代码到新的进程。

二、fork进阶知识

http://blog.chinaunix.net/uid-26495963-id-3150116.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

fork()函数详解 的相关文章

  • 如何“grep”连续流?

    可以用吗grep在连续的流中 我的意思是有点tail f
  • 是否可以找到哪个用户位于 localhost TCP 连接的另一端?

    这是一个编程问题 但它是 Linux Unix 特定的 如果我从本地主机获得 TCP 连接 是否有一种简单的方法可以告诉哪个用户在 C 程序内建立了连接而无需 shell 我知道这对于 Unix 域套接字来说并不太难 我已经知道远程 IP
  • 如何删除树莓派的相机预览

    我在我的 raspberryPi 上安装了 SimpleCv 并安装了用于使用相机板的驱动程序 uv4l 驱动程序 现在我想使用它 当我在 simpleCV shell Camera 0 getImage save foo jpg 上键入时
  • xdotool 类型需要很长时间并导致整个桌面冻结

    我一直在使用xdotool type过去只能在快捷方式上输入耸肩xdotool type 这可行 但总是需要相当长的时间 并导致整个桌面冻结 完全冻结 而不仅仅是输入 几秒钟 不过并没有太打扰我 现在我需要一种方法来从文件中读取内容 对其进
  • 如何使用libaudit?

    我试图了解如何使用 libaudit 我想接收有关使用 C C 的用户操作的事件 我不明白如何设置规则 以及如何获取有关用户操作的信息 例如 我想获取用户创建目录时的信息 int audit fd audit open struct aud
  • 变量作为 bash 数组索引?

    bin bash set x array counter 0 array value 1 array 0 0 0 for number in array do array array counter array value array co
  • 在中断时获取 current->pid

    我正在Linux调度程序上写一些东西 我需要知道在我的中断到来之前哪个进程正在运行 当前的结构可用吗 如果我在中断处理程序中执行 current gt pid 我是否可以获得我中断的进程的 pid 你可以 current gt pid存在并
  • 如何阅读shell命令的源代码?

    我想阅读编写linux命令的实际源代码 我已经获得了一些使用它们的经验 现在我认为是时候与我的机器进行更深层次的交互了 我在这里找到了一些命令http directory fsf org wiki GNU http directory fs
  • 如何使用ffmpeg重叠和合并多个音频文件?

    我正在尝试将多个音频文件合并到一个文件中 但我可以使用以下命令来连接 而不是连接 ffmpeg v debug i file1 wav i file2 wav i file3 wav filter complex 0 0 concat n
  • 远程linux服务器到远程linux服务器大型稀疏文件复制 - 如何?

    我有两台 CentOS 5 4 服务器 每台服务器上都安装了 VMware Server 假设我始终对 vmware 虚拟机使用稀疏文件 将虚拟机文件从一台服务器复制到另一台服务器的最可靠 最快速的方法是什么 虚拟机的文件复制起来很痛苦 因
  • Xenomai 中的周期性线程实时失败

    我正在创建一个周期性线程 它在模拟输出上输出方波信号 我正在使用 Xenomai API 中的 Posix Skin 和 Analogy 我使用示波器测试了代码的实时性能 并查看了方波信号 频率为 1kHz 的延迟 我应该实现 250us
  • Linux 文本文件操作

    我有一个格式的文件 a href a href a href a href 我需要选择 之后但 之前的文本 并将其打印在行尾 添加后 例如 a href http www wowhead com search Su a a a a a
  • grails 上的同步块在 Windows 上有效,但在 Linux 上无效

    我有一个 grails 应用程序 它依赖于服务中的同步块 当我在 Windows 上运行它时 同步按预期工作 但当我在 ams linux 上运行时 会出现 StaleObjectStateException 该问题在以下示例中重现 cla
  • perf stat中的cycles注释是什么意思

    8 014196 task clock 0 004 CPUs utilized 204 context switches 0 025 M sec 32 cpu migrations 0 004 M sec 0 page faults 0 0
  • CentOS目录结构是树形的吗?

    CentOS 上有相当于树的东西吗 如果你的 Centos 系统上没有安装 tree 无论如何我通常建议服务器设置使用最小安装磁盘 你应该在命令行中输入以下内容 yum install tree y 如果没有安装 那是因为您没有正确的存储库
  • 如何在 Linux 主机上的 docker 容器中挂载目录 [重复]

    这个问题在这里已经有答案了 我想将一个目录从 docker 容器挂载到本地文件系统 该目录是网站根目录 我需要能够使用任何编辑器在本地计算机上编辑它 我知道我可以跑docker run v local path container path
  • 如何从linux命令行运行.exe可执行文件? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我在 Windows 中有一个 abc exe 可执行文件 我可以使用 DOS 命令提示来执行此应用程序 并为其提供一些运行时变量 我想从
  • 无法仅在控制台中启动 androidstudio

    你好 我的问题是下一个 我下载了Android Studio如果我去 路径 android studio bin 我执行studio sh 我收到以下错误 No JDK found Please validate either STUDIO
  • 如何查明 Ubuntu 上安装了哪个版本的 GTK+?

    我需要确定 Ubuntu 上安装了哪个版本的 GTK 男人似乎不帮忙 这个建议 https stackoverflow com a 126145 会告诉您安装了哪个 2 0 的次要版本 不同的主要版本将具有不同的包名称 因为它们可以在系统上
  • 将数组传递给函数名称冲突

    Specs GNU bash 版本 3 1 17 无法升级 Premise 我一直在摆弄数组 我想知道是否有任何方法可以让函数的本地变量与所述函数外部的数组同名 Example 在下面的示例中 我将尝试显示该问题 Working bin b

随机推荐

  • 我朋友月薪5w,跟他聊过之后,才知道差距在哪里!

    当我开始工作的时候 年薪50万对于我来说是一个遥不可及的幻想 我认为作为一名普通的软件测试工程师 月薪2w已经是天花板了 然而随着时间的推移和经验的积累 看到越来越多的同行拿到高薪时 我才意识到束缚我薪水的不是行业的天花板 而是我自身技术能
  • 跑pytorch报错: The NVIDIA driver on your system is too old

    今天运行pytorch代码发现报错 The NVIDIA driver on your system is too old found version 8000 Please update your GPU driver by downlo
  • 计算机网络基础应用课程标准,王建波《计算机网络基础》课程标准.doc

    文档介绍 设计者 王建波指导老师 蒋本立廖兴张光清设计时间 2013年7月适用专业 计算机网络专业 计算机应用专业 计算机网络基础 课程标准设计者 王建波指导老师 蒋本立廖兴张光清设计时间 2013年7月适用专业 计算机网络专业 计算机应用
  • 在Raspberry Pi上使用PySimpleGUI创建图表

    PySimpleGUI python库在本地GUI和Web界面具有相同代码的能力中脱颖而出 PySimpleGUI并非以图表包为重点 而是具有画布和图形元素 可让您创建实时条形图和实时趋势图 图形元素入门 图形元素可以具有不同的坐标方向 例
  • 用Dockerfile制作一个python环境案例,值得收藏

    Dockerfile文件 无后缀 FROM python 3 7 设置 python 环境变量 ENV PYTHONUNBUFFERED 1 创建 code 文件夹并将其设置为工作目录 RUN mkdir code WORKDIR code
  • 史上最完美的Android沉浸式状态导航栏攻略

    前言 最近我在小破站开发一款新App 叫高能链 我是一个完美主义者 所以不管对架构还是UI 我都是比较抠细节的 在状态栏和导航栏沉浸式这一块 我还是踩了挺多坑 费了挺多精力的 这次我将我踩坑 适配各机型总结出来的史上最完美的Android沉
  • 傻瓜电梯项目实现

    目录 文档介绍 package lift entity Elevator java Entity java Floor java package lift Pretreatment Pretreatment java package lif
  • Elasticsearch——document相关原理

    1 document数据路由原理 1 1 document路由到shard上是什么意思 一个index的数据会被分为多片 每片都在一个shard中 所以说 一个document 只能存在于一个shard中 当客户端创建document的时候
  • [计算机毕业设计]大数据疫情分析与可视化系统

    前言 大四是整个大学期间最忙碌的时光 一边要忙着准备考研 考公 考教资或者实习为毕业后面临的就业升学做准备 一边要为毕业设计耗费大量精力 近几年各个学校要求的毕设项目越来越难 有不少课题是研究生级别难度的 对本科同学来说是充满挑战 为帮助大
  • mysql报错 -- (errno: 13 - Permission denied)

    重启服务器后 mysql没有自启动 手动启动的时候报错 后面经一番折腾后强行用root身份启动后又发现原有的数据库表都不见了 mysql 报错 ERROR 1018 HY000 Can t read dir of db translator
  • 模型选择+过拟合+欠拟合

    模型选择 当我们训练模型时 我们只能访问数据中的小部分样本 最大的公开图像数据集包含大约一百万张图像 而在大部分时候 我们只能从数千或数万个数据样本中学习 将模型在训练数据上拟合的比在潜在分布中更接近的现象称为过拟合 overfitting
  • 从代码角度理解DETR

    一个cnn的backbone 提图像的feature 比如 HWC 同时对这个feature做position embedding 然后二者相加 在Transformer里面就是二者相加 输入encoder 输入decoder 这里有obj
  • Matlab中实现图像处理的工作流程

    一 识别流程 Receipt Identification Workflow Working with Images in MATLAB Import display and manipulate color and grayscale i
  • Angular4.0_完善在线竞拍应用路由

    路由实战思路 一 创建商品详情组件 显示商品的图片和标题 使用Angular命令行工具生成一个新的组件 ng g component productDetail product detail component ts import Comp
  • latex Elsevier 模板给作者加脚注

    Elsevier 模板给作者加脚注 thanks 无效 网上有说使用 corref cor1 cortext cor1 Corresponding author 但是实测发现不行 只能加一个标注 再加一个就是两个 还有说使用 authorn
  • SVM算法(Support Vector Machine)

    一 SVM 支持向量机 support vector machines SVM 是一种二分类模型 将实例的特征向量映射为空间中的一些点 SVM 的目的就是想要画出一条线 以 最好地 区分这两类点 以至如果以后有了新的点 这条线也能做出很好的
  • GIT reset

    Git Reset 转载Git Reset reset 用于回退commit 主要有三个参数 hard mixed soft working工作区 cache暂存区 repository本地库 hard 清空 清空 清空 mixed 保留
  • window系统启动redis和清除缓存

    一 启动redis dos命令行方式 c user john gt d 进入所在盘 D gt cd D Redis x64 3 2 100 进入安装目录 D gt cd D Redis x64 3 2 100 gt redis server
  • git提交新项目操作笔记

    git提交新项目操作笔记 1 本地安装git环境 下载安装包安装即可 2 初始化git项目 生成 git 配置目录 进入项目根目录 右键 git bash here打开控制台 输入git init即可完成 3 将项目加入本地git仓库 gi
  • fork()函数详解

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