fork函数,为什么有两次返回?

news2024/11/26 7:34:48

前言

fork函数用于创建一个新进程,称为子进程,它与旧进程(称为系统调用fork的进程)同时运行,此进程称为父进程

创建新的子进程后,两个进程将执行fork()系统调用之后的下一条指令。子进程使用相同的pc(程序计数器)、相同的CPU寄存器、在父进程中使用的相同打开文件。它不需要参数并返回一个整数值。

下面是fork()返回的不同值:

  • 负值:创建子进程失败。
  • 零:返回到新创建的子进程。
  • 正值:返回父进程或调用者。该值包含新创建的子进程的进程ID

失败的两个主要原因:

  1. 当前系统的进程数已经达到了系统规定的上限,这时Error Codes的值被设置为 EAGAIN
  2. 系统内存不足,这时Error Codes的值被设置为 ENOMEM

代码示例

#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
 
int main() {
    printf("before fork: \n");
    pid_t pid = fork();			//进程从当前位置开始分裂为父进程和子进程,分别开始交替向前并发执行,区分在于pid不同
    printf("after fork: \n");
    if (pid == -1) {
        perror("fork");
    }
 
    if (pid > 0) {
        printf("pid: %d\n", pid);
        //程序在父进程,返回子进程的pid
        printf("this is parent process, pid: %d, ppid: %d\n",  getpid(), getppid());
    } else if (pid == 0){
        //程序在子进程,它没有子进程,返回0
        printf("this is child process, pid: %d, ppid: %d\n",  getpid(), getppid());
    }
 
    for (int i = 0; i < 5; i++) {
        printf("i: %d, pid: %d\n", i, getpid());
        sleep(1);
    }
 
    return 0;
}

输出结果如下:

before fork: 			
after fork: 				#父进程先执行
pid: 146087					#父进程的返回值是子进程的pid
this is parent process, pid: 146086, ppid: 144773
i: 0, pid: 146086			#父进程自己的pid
after fork: 				#子进程开始执行
this is child process, pid: 146087, ppid: 146086 #子进程pid, ppid
i: 0, pid: 146087  				#子进程pid		linux时间片为4ms~x00ms
i: 1, pid: 146086				#父进程pid
i: 1, pid: 146087
i: 2, pid: 146086
i: 2, pid: 146087
i: 3, pid: 146086
i: 3, pid: 146087
i: 4, pid: 146086
i: 4, pid: 146087

为什么fork会返回两次?

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

fork调用的一个奇妙之处就是 它仅仅被调用一次却能够返回两次,它可能有三种不同的返回值:

(1)在父进程中,fork返回新创建子进程的进程ID;
(2)在子进程中,fork返回0;
(3)如果出现错误,fork返回一个负值。

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

引用一位网友的话来解释fork函数返回的值为什么在父子进程中不同。“其实就相当于链表,进程形成了链表,父进程的fork函数返回的值指向子进程的进程id, 因为子进程没有子进程,所以其fork函数返回的值为0.

调用fork之后,数据、堆、栈有两份,代码仍然为一份但是这个代码段成为两个进程的共享代码段都从fork函数中返回,箭头表示各自的执行处。当父子进程有一个想要修改数据或者堆栈时,两个进程真正分裂。

子进程代码是从fork处开始执行的, 为什么不是从#include处开始复制代码的?这是因为fork是把 进程当前的情况拷贝一份 , 执行fork时,进程已经执行完了前面部分逻辑。fork只拷贝下一个要执行的代码到新的进程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/740362.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

网络传输层协议详解(TCP/UDP)

目录 一、TCP协议 1.1、TCP协议段格式 1.2、TCP原理 确认应答机制 超时重传机制 (安全机制) 连接管理机制(安全机制) 滑动窗口 流量控制(安全机制) 拥塞控制 延迟应答(效率机制) 捎带应答&#xff08;效率机制&#xff09; ​编辑面向字节流(粘包问题) 缓…

[pyqt5]如何给工具栏图标添加资源文件

第一步新建一个qrc文件 首先新建一个 .qrc 文件&#xff0c;内容格式如下&#xff1a; <RCC><qresource prefix"/" ><file>img/image1.png</file><file>img/image2.png</file><file>img/image3.png</file></qr…

解决win11系统下vivado使用RTL分析闪退、小蓝熊easy anti chat无法启动问题

最近在接触使用vivado时被这个软件庞大的包体和繁多的报错搞得焦头烂额&#xff0c;经过多次尝试&#xff0c;我解决了两个困扰我许久的关乎软件正常使用的问题&#xff0c;将解决办法分享给大家。 一.RTL analysis运行闪退 这个问题关系到程序的正常使用&#xff0c;主要发生…

css animation动画

代码 <!DOCTYPE html> <html ng-app"my_app"><head><meta charset"utf-8"><title></title><script type"text/javascript"></script><style type"text/css">.my-animation {p…

关于海外的应用商店优化

应用商店优化的工作方式与搜索引擎优化 (SEO) 类似&#xff0c;但它有专门为应用商店设计的专业功能。应用商店优化可以帮助应用程序出现在应用商店的顶部结果中&#xff0c;从而提高下载转化率和应用安装量&#xff0c;并且对于我们的应用也有长期可见性。 应用商店优化是一个…

本地用户管理(NETBASE第九课)

本地用户管理(NETBASE第九课) 本地用户&#xff1a;用户本地创建、本地存储、本地登录且只能登录本地一台计算机。 1.认识用户帐户&#xff1a; 1&#xff09;Windows帐户有帐户名、有密码、用户安全标识&#xff08;SID&#xff09; 注:SID安全标识符&#xff08;身份证号…

数据结构-二叉树的代码实现(详解)

内容&#xff1a;二叉树的前、中&#xff0c;后序遍历&#xff0c;层序遍历&#xff0c;二叉树节点个数&#xff0c;叶子节点个数&#xff0c;二叉树高度&#xff0c;第k层节点的个数&#xff0c;查找某个节点&#xff0c;二叉树销毁&#xff0c;判断是否为完全二叉树 目录 前…

科研热点|《电气工程领域高质量科技期刊分级目录(2022版)》公示!

为贯彻落实《关于深化改革 培育世界一流科技期刊的意见》&#xff0c;推进国内外科技期刊的同质等效使用&#xff0c;助力我国科技期刊高质量发展&#xff0c;在中国科协的统一部署下&#xff0c;中国电工技术学会制定《电气工程领域高质量科技期刊分级目录发布工作实施方案&am…

【HarmonyOS】ArkTS学习之页面转场动画的实现

【关键字】 ArkTS、转场动画、PageTransitionEnter、PageTransitionExit 【介绍】 动画交互的实现是一种提升用户体验的方式。动画分为属性属性动画、显示动画、转场动画和路径动画&#xff0c;而转场动画又包含页面间转场、组件内转场和共享元素转场。我觉得页面转场动画挺有趣…

电机的调压调速和PWM调速方法的性能比较、应用场景简介

电机的调压调速和PWM调速是两种不同的电机控制方式。 调压调速&#xff1a;调压调速是通过改变电机输入电压的大小来控制电机的转速和扭矩。通过调节电压&#xff0c;可以改变电机的转矩特性和转速。这种调速方式适用于直流电机和某些类型的交流电机&#xff0c;如感应电动机。…

Windows电源模式(命令行)

一、简介 windows使用powercfg.exe来控制电源方案,像cmd.exe一样,powercfg.exe也是windows自带的。 powercfg命令行选项 选项说明/?、-help显示有关命令行参数的信息。/list、/L列出所有电源方案。/query、/Q显示电源方案的内容。

华为云CodeArts DevSecOps系列插件——助力更高效的软件研发

HDC期间入驻华为云&#xff0c;可参与Toolkit插件抽奖活动&#xff0c;活动链接在文末 一、前言 DevOps的概念想必大家都不陌生&#xff0c;它是一组过程、方法与系统的统称&#xff0c;通过它可以对交付速率、协作效率、部署频率速率、质量、安全和可靠性等进行提升改善。相比…

Linux——信号发送代码

目录 一.信号集操作函数 sigpromask函数 代码详解&#xff1a; ​编辑 考虑情况一&#xff1a;对多个信号的屏蔽 考虑情况二&#xff1a;取消对信号的阻塞 运行结果&#xff1a; 考虑情况三&#xff1a;若不想让进程退出&#xff0c;采用自定义捕捉信号方式&#xff01;…

Java阶段五Day02

Java阶段五Day02 文章目录 Java阶段五Day02MAVEN-聚合(多模块3)回顾多模块2个特性依赖:继承: 聚合场景聚合目的实现聚合聚合总结 远程仓库远程仓库概念配置settings.xml远程库配置注意事项 GIT详细学习git概括git历史本地版本控制相关命令git分支管理分支管理基本概念分支管理相…

axios请求错误处理Uncaught runtime errors:handleError@webpack-internal:///./node_modules/webpack-dev-server

项目环境&#xff1a; vue3.2.13 vue-cli5.0.0 注&#xff1a;该问题只是出现在开发环境&#xff0c;打包后是不会出现的。 问题描述&#xff1a; 由于需要新开一个开发项目&#xff0c;引入必备网络请求axios及他的副手&#xff08;集中处理请求及返回数据&#xff09;&a…

springboot+MySQL大学生体质测试管理系统

功能需求分析的任务是通过详细调查大学生体质测试的测试信息管理系统要处理的所有对象&#xff0c;通过充分了解大学生体质测试管理系统的工作流程&#xff0c;明确使用者的各种需求&#xff0c;充分思考之后可能扩充和改变的情况&#xff0c;然后在这个基础上来设计数据库。

C#(五十九)之三种数据结构 stack queue sortedList

堆栈&#xff08;Stack&#xff09;&#xff1a; 代表了一个后进先出的对象集合。当您需要对各项进行后进先出的访问时&#xff0c;则使用堆栈。当您在列表中添加一项&#xff0c;称为推入元素&#xff0c;当您从列表中移除一项时&#xff0c;称为弹出元素。 Stack 类的方法和…

UVM中transaction中数据持续时间的控制

一、代码 首先需要确认持续时间是在driver中进行控制 其中data_size就是数据的持续时钟周期个数

如何看待中国工业MES系统的发展现状?

如何看待中国工业MES系统的发展现状&#xff1f; MES系统在中国工厂推进是否举步维艰&#xff0c;MES系统是否多数华而不实&#xff1f;中国工业化的前途在何方&#xff1f; 什么是MES—— 制造执行系统&#xff08;MES&#xff09;一种用于监控、控制和优化制造过程的软件系统…

多元回归预测 | Matlab基于粒子群算法(PSO)优化高斯过程回归(PSO-GPR)的数据回归预测,matlab代码,多变量输入模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元回归预测 | Matlab基于粒子群算法(PSO)优化高斯过程回归(PSO-GPR)的数据回归预测,matlab代码,多变量输入模型 评价指标包括:MAE、RMSE和R2等,代码质量极高,方便学习和替换数据。要求2018版本及以上。 部分…