fork两次不同返回值的实现

两次fork产生进程ID分析 进行两次fork,会产生几个进程,他们的ID是多少,本文通过实例进行分析。基本概念:pid_t:pid_t是typedef定义的类型,表示进程的id。在sys/types.h中定义:typedef short   pid_t;所以说pid_t就是一个short类型的变量,实际表示的是内核中进程表的索引。pid_t getpid(void);返回目前进程的ID。pid_t fork(void... 阅读详情

【NOTE4】

首先必须有一点要清楚,函数的返回值是储存在寄存器eax中的。

其次,当fork返回时,新进程会返回0是因为在初始化任务结构时,将eax设置为0;

在fork中,把子进程加入到可运行的队列中,由进程调度程序在适当的时机调度运行。也就是从此时开

始,当前进程分裂为两个并发的进程。

无论哪个进程被调度运行,都将继续执行fork函数的剩余代码,执行结束后返回各自的值。

【NOTE5】

对于fork来说,父子进程共享同一段代码空间,所以给人的感觉好像是有两次返回,其实对于调用fork的

父进程来说,如果fork出来的子进程没有得到 调度,那么父进程从fork系统调用返回,同时分析sys_fork

知道,fork返回的是子进程的id。再看fork出来的子进程,由 copy_process函数可以看出,子进程的返回地

址为ret_from_fork(和父进程在同一个代码点上返回),返回值直接置为0。所以当子进 程得到调度的时

候,也从fork返回,返回值为0。

关键注意两点:1.fork返回后,父进程或子进程的执行位置。(首先会将当前进程eax的值做为返回值)2.

两次返回的pid存放的位置。(eax中)

进程调用copy_process得到lastpid的值(放入eax中,fork正常返回后,父进程中返回的就是lastpid)

子进程任务状态段tss的eax被设置成0,
f
ork.c 中

p->tss.eax=0;(如果子进程要执行就需要进程切换,当发生切换时,子进程tss中的eax值就调入eax寄存

器,子进程执行时首先会将eax的内容做为返回值)

当子进程开始执行时,copy_process返回eax的值。

fork()后,就是两个任务同时进行,父进程用他的tss,子进程用自己的tss,在切换时,各用各的eax中的值.

所以,“一次调用两次返回”是2个不同的进程!

看这一句:pid=fork()

当执行这一句时,当前进程进入fork()运行,此时,fork()内会用一段嵌入式汇编进行系统调用:int

0×80(具体代码可参见内核版本0.11的unistd.h文件的133行_syscall0函数)。这时进入内核根据此前写入

eax的系统调用功能号 便会运行sys_fork系统调用。接着,sys_fork中首先会调用C函数find_empty_process

产生一个新的进程,然后会调用C函数 copy_process将父进程的内容复制给子进程,但是子进程tss中的eax

值赋值为0(这也是为什么子进程中返回0的原因),当赋值完成 后,copy_process会返回新进程(该子进

程)的pid,这个值会被保存到eax中。这时子进程就产生了,此时子进程与父进程拥有相同的代码空 间,

程序指针寄存器eip指向相同的下一条指令地址,当fork正常返回调用其的父进程后,因为eax中的值是新

创建的子进程号,所以,fork()返回 子进程号,执行else(pid>0);当产生进程切换运行子进程时,首先会

恢复子进程的运行环境即装入子进程的tss任务状态段???,其中的 eax值(copy_process中置为0)也会被装入

eax寄存器,所以,当子进程运行时,fork返回的是0执行if(pid==0)。

【NOTE5】

理解它关键在于理解堆栈的切换和压栈,弹栈!

关于子进程的返回:

子进程复制了父进程的栈内容,从高到低

SS

ESP

EFLAGS

CS

EIP 此是int 0×80 的下一条指令,也是子进程开始执行的地方!!!!

DS

ES

FS

EDX

ECX

EBX

GS

ESI

EDI

EBP

EAX(0)

由于 EAX = 0,所以子进程返回 0 给 fork.

注:新进程的用户栈设为其父进程的用户栈(最后弹出的SS,ESP)。如果父子进程以copy_on_write方式共用

用户堆栈

(Linux之下就是这样的),而且在此之前父进程修改了该堆栈(如果父进程先返回,这几乎是肯定的),那

么,系统已经为父进程创建了该用户栈的副本,父进程原来的用户栈留给了子进程。那么新进程的系统

栈已经清空,新进程回到了用户态,返回到了函数fork。

制作 img系统镜像的详细方法       I.MX6开发板目前支持从TF卡和eMMC启动,启动时,由于各个不同的启动文件对路径有不同的要求,例如uboot文件要求位于启动设备的某个块,dtb文件要求在FAT分区上,文件系统要求在Linux分区上,基于此,我们目前采用将映像制作成img文件的方式,这样可以更简单完成对启动卡的制作。 关于如何制作img,方法如下:方法一  Windows下面利用Win32工具1.   准备我司提供... 阅读详情

相关推荐

国产FPGA逆袭!深度评测复旦微RFVU3P5G核心板在相控阵雷达中的表现

本文深度评测了复旦微RFVU3P5G核心板在相控阵雷达中的实战表现。该核心板凭借射频直采架构、高采样率ADC/DAC及丰富的DSP资源,在多通道同步精度、动态范围及系统稳定性等关键指标上表现出色,展现了国产FPGA在高端雷达应用中的硬核实力与供应链自主价值。

b0c1d2的博客 722

fork函数的理解

fork函数返回值,创建子进程

Latecomessnow的博客 2179

【软件使用】Calibre部分提参的实战技巧与常见问题解析

本文详细解析了Calibre部分提参(Partial PEX)的实战技巧,重点介绍了如何利用HCELL与XCELL文件高效排除已知模块,实现精准的寄生参数提取,从而快速定位后仿真中的时序与信号完整性问题。文章涵盖了从图形界面到命令行的完整操作流程,并提供了常见问题(如时钟失真、模块“消失”)的深度Debug指南与最佳实践,助力芯片设计工程师提升验证效率。

yhn456789的博客 1027

fork()函数的底层实现原理

在Linux中,fork函数是非常重要的函数,他从一个已存在的进程中创建一个新进程;新进程为子进程,而原进程称为父进程。接下来我们一起来系统的解析一下fork函数的调用原理: 1、fork函数原型 #include pid_t fork(void) 返回值: pid_t 是进程描述符,实质就是一个int,如果fork函数调用失败,返回一个负数,调用成功则返回两个值:0和子进程ID。 函数功能: 以...

qq_42230338的博客 3915

Unity游戏开发客户端Unity基础

Unity游戏开发客户端面经 之 Unity 篇

Sea3752的博客 2万+

PICO4 VR开发调试神器:用Live Preview Plugin实现电脑串流,告别反复打包烧录的繁琐流程

本文详细介绍了PICO4 VR开发中如何使用Live Preview Plugin实现电脑串流,显著提升开发效率。通过实时预览和调试功能,开发者可以避免反复打包烧录的繁琐流程,特别适用于Unity环境下的VR应用开发。文章涵盖环境配置、连接设置、实时调试技巧及性能优化方案,是PICO4开发者的必备指南。

weixin_34110970的博客 418

linux中fork()函数详解(原创 实例讲解)

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

木牛的博客 1009

VS配置RTKLIB(卫星定位开源代码)环境

@RTKlib代码调试教程-Visual Studio 2019 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 ##RTKLIB-rtklib_2.4.3 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 @RTKlib代码调试教程-Visual Studio 2019 提示:这里可以添加本文要记录的大概内容: 例如:随着人工智能的不断发展,机器学习这门技

qq_42209977的博客 4486

Linux中fork函数详解(附图解与代码实现)

我们先来看个代码,判断一下这个代码的输出结果会是什么样的,先不要去看运行结果,判断好后再去看看是否和你的预期结果一致。 #include<stdio.h> #include<unistd.h> #include<stdlib.h> #include<string.h> int main(void) { pid_t pid; pid = fork(); printf("xxxxxxxxxx\n"); while (1) { sleep(1)

m0_53133879的博客 9395

CCS导入工程报错?手把手教你安装C2000编译器(附最新下载链接)

本文详细解析CCS导入工程报错的常见原因,并提供三种安装C2000编译器的解决方案(TI官网离线安装、CCS内置更新和App Center渠道)。通过版本匹配技巧和路径配置要点,帮助开发者快速解决编译器缺失问题,确保项目顺利导入和编译。

weixin_30374009的博客 661

49、非合作目标运动参数估计与状态滤波方法研究

本文研究了非合作空间目标的运动参数估计与状态滤波方法。通过分析目标的章动运动特性,建立了运动方程,并分别提出了基于最小二乘法的质心运动参数估计方法和旋转运动参数估计方法。同时,设计了误差状态卡尔曼滤波器(ESKF)用于姿态滤波和角速度估计,以提高估计精度。仿真实验验证了所提方法的有效性,能够准确估计目标的运动参数和状态信息,为在轨服务提供了技术支持。

gpt4scribbler的博客 88

Linux保姆级介绍系统接口fork()函数

​ fork()函数是一个创建新进程(子进程)的一个系统接口。头文件由两个系统接口头文件sys/types.h和unistd.h所支持。​​注意:返回值类型为pid_t,用来标识和描述进程ID,本质是无符号整型unsigned int。

专业而不失有趣的C++编程老师一枚~ 757

多模态轨迹预测:行人、车辆的交互式推理

多模态轨迹预测:行人、车辆的交互式推理 ,人工智能,计算机视觉,大模型,AI,本文围绕多模态轨迹预测中行人与车辆的交互式推理展开,介绍了其定义,即综合多种信息预测交通参与者未来多种轨迹。涵盖基础概念如轨迹表示、模态、交互关系,技术框架包括数据处理、特征提取、预测模型(物理、机器学习、深度学习模型等)及结果评估。还探讨了交互式推理方法、面临的不确定性处理等挑战、应用场景、未来发展方向、相关工具及实际案例,展现了该技术在智能交通等领域的重要性与发展潜力。​

不踩坑,不知道坑有多深;不总结,踩过的坑白踩。 14万+

fork()两次不同返回值的实现

http://www.cnblogs.com/hongzg1982/articles/2152093.html fork()两次不同返回值的实现 【NOTE4】 首先必须有一点要清楚,函数的返回值是储存在寄存器eax中的。 其次,当fork返回时,新进程会返回0是因为在初始化任务结构时,将eax设置为0; 在fork中,把子进程加入到可运行的队列中,由进程调度程序在适

linuxheik的专栏 699

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

fork()函数的两次返回的具体情况

导读: fork()函数的两次返回的具体情况对于fork来说,父子进程共享同一段代码空间,所以给人的感觉好像是有两次返回,其实对于调用 fork的父进程来说,如果fork出来的子进程没有得到调度,那么父进程从fork系统调用返回,同时分析sys_fork知道,fork返回的是子进 程的id。再看fork出来的子进程,由copy_process函数可以看出,子进程的返回地址为ret_fro

linson_zhou的专栏 1068

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

FORK()函数的两次返回的具体情况

FORK()函数的两次返回的具体情况对于fork来说,父子进程共享同一段代码空间,所以给人的感觉好像是有两次返回,其实对于调用 fork的父进程来说,如果fork出来的子进程没有得到调度,那么父进程从fork系统调用返回,同时分析sys_fork知道,fork返回的是子进 程的id。再看fork出来的子进程,由copy_process函数可以看出,子进程的返回地址为ret_from_fork(

fatsandwich的专栏 2133

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

关于多进程编程中fork()函数返回两次的探究

可以每个接触到多进程编程的人在遇到fork()函数的时候都会由一些疑惑,它怎么能返回两次?而且返回值不同。对于以前的认知大家都知道一个函数只能返回依次啊。 呵呵,这就是fork的神奇所在,它为什么这么神奇?它是怎么实现的?下面我根据自己得理解简单的说一下,不过另外也欢迎大家的讨论。 首先要明白的就是fork函数的作用,它是用来创建一个子进程,和父进程一样的子进程,就是父进程的一个副本。 子进程将会有自己的地址空间,并且会获得父进程的数据段的副本以及堆栈的副本,所获得的副本都是精确拷贝。所谓副本就是一模一样的

Ternence_zq的博客 497

linux进程概念(三)(fork的介绍与使用)

一般而言,fork之后的代码父子共享。当我们调用fork之后,父进程就会创建子进程,并且之后的代码部分父子进程是共享的,但是,因为fork()会由父进程和子进程分别执行return,进行两次返回,在id层面就会发生写时拷贝,导致父子进程id变成不同的值,所以后续可以通过对id进行if else判断,来对父子进程进行分流,让父子执行不同的代码块。每次运行相同的程序,他的pid会变,但他的ppid不会变,但每次登录xshell时,系统会单独创建bash进程,ppid会发生改变,即创建命令行解释的进程。

2401_82669661的博客 733

c++ fork函数

fork 分叉函数 成功时返回两个值,子进程返回0,父进程返回子进程标记 一个进程通过调用fork函数,创建一个新进程。新进程成为子进程(child process) for函数被调用一次,但返回两次。 注意,通过判断fork返回值,是0还是非0(非-1),即可控制让父子进程做不同的事情。 代码 //让子进程做一些事情后退出 //父进程不受影响,继续执行 if (0 == fork()) {

林多 4412

unix/linux fork函数实例分析

unix/linux fork()实例分析 打算分析一下fork() 函数。 代码 #include <stdio.h> #include <sys/types.h> int main(){ pid_t pid; pid = fork(); if(pid == 0){ printf("Run in Child proces...

bwxzing的专栏 339

fork()两次不同返回值

【NOTE4】 首先必须有一点要清楚,函数的返回值是储存在寄存器eax中的。 其次,当fork返回时,新进程会返回0是因为在初始化任务结构时,将eax设置为0; 在fork中,把子进程加入到可运行的队列中,由进程调度程序在适当的时机调度运行。也就是从此时开始,当前进程分裂为两个并发的进程。 无论哪个进程被调度运行,都将继续执行fork函数的剩余代码,执行结束后返回各自的值。 【NOTE5...

Kk_01110001B的博客 759

为什么fork调用会返回两次

fork大家可能都比较熟悉,调用一次返回2次,返回pid>0为父进程,pid=0为子进程。一直对fork方法如何返回两次有些疑惑,函数调用一次只会返回一个只,fork怎么会返回2次?之前查过原因,时间久了有些模糊了,今天上网又查了下,其实大家都说的“返回两次”在表达上时不清楚的。fork实际上并不是执行两次,它依然返回了一次,准确地说是一次多一点,只是OS对fork进行的操作使得我们看起来它返回了两次

wangww631的专栏 8915
上一篇: Linux兴趣小组暑假留校第四次讲座总结
下一篇: 一看就会,一看就懂,快速上手Git
FallingU
博客等级 码龄11年 61粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值