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。

进程通信之三 父进程传参数与子进程返回值 《进程通信之三 父进程传参数与子进程返回值》 http://blog.youkuaiyun.com/morewindows/article/details/8683830 配套程序。本篇介绍一个简单而又实用的进程通信方式——父进程向子进程传入参数并获取子进程返回值。这个非常简单: 1.父进程向子进程传入参数可以由CreateProcess()函数来完成,注意子进程是通过GetCommandLine()来获取这个参数而且不是char *argv[]。 2.父进程要获取子进程的返回值可以在等待子进程结束后通过GetExitCodeProcess并传入子进程句柄来获取子进程中main或WinMain函数的返回值。 立即下载

相关推荐

Python与numpy版本兼容性排查指南

本文详细解析了Python与numpy版本兼容性问题,提供了快速诊断和解决版本冲突的实用方法。通过查看版本信息、使用官方兼容性对照表以及降级或升级环境等方案,帮助开发者有效避免常见的报错问题,如'ImportError'和'AttributeError'。文章还介绍了使用虚拟环境和requirements.txt等工程实践,确保项目依赖的稳定性。

weixin_29089057的博客 319

fork函数的理解

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

Latecomessnow的博客 2179

手把手教你用STM32单片机控制双向可控硅调光(附完整代码+电路图)

本文提供了一套完整的STM32单片机控制双向可控硅实现灯光无级调光的实战方案。详细讲解了硬件电路设计,包括过零检测与隔离驱动,并剖析了基于定时器中断的软件核心逻辑,通过精准的相位角计算实现平滑的灯光强度控制。附有完整代码与电路图,适合嵌入式开发者实践。

weixin_29194255的博客 952

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

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

qq_42230338的博客 3915

阿里云大模型ACP认证模拟考试(三)

【摘要】:在阿里云大模型高级工程师 ACP 认证暂无真题题库的现状下,模拟题具有重要意义。其依照真实考试设计,涵盖题型、题量与分值分布,助力考生熟悉考试框架,合理分配答题时间精力,提升效率。同时,模拟题紧扣官方课程,能帮助考生精准定位知识盲点,如大模型架构原理和通义千问应用实践等重点内容,以便针对性完善知识体系。此外,通过练习模拟题,考生可掌握不同题型的解题思维与技巧,快速洞察复杂题目本质,提高答题准确率。

davidkorhenn的博客 3578

链家二手房信息爬取(内附完整代码)

链家二手房信息爬取1.简介2. 爬虫思路2.1 网页分析2.2 详情页分析2.3 不同页码的爬取2.4 解决链家只显示100页数据2.5 简单的反爬与进度条显示3. 总结 1.简介   最近帮同学爬取了链家在售二手房的信息,这是本人学习爬虫以来爬取数据最多的一次,就想着写个博客记录一下。   本次爬虫是利用python+jupyter notebook实现的,用到的第三方库如下: import pandas as pd # 数据存储 import requests # 网页内容获取 import re #

qq_46256922的博客 3万+

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

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

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

Qt制作大数据可视化大屏展示电子看板

Qt制作大数据可视化大屏展示电子看板 解决当前最火的大数据可视化大屏展示,整个项目通过Qt开发,集成了QML/QChart/ECharts及自定义控件等模块,所有的可视化控件都可以集成到其中。可以随意增加和减少模块,各个模块可以随意拖拽,整体可以个性化布局。模块标题栏可自定义,包括标题文本信息、文本颜色、宽度/高度、背景颜色、按钮个数等功能,满足各个样式需求。 实例中主要展示了现成的一些仪表盘...

Qt自定义控件及应用开发 7707

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

uniapp - 超详细的 H5 公众号网页微信登录示例代码,提供从 0-1 公众号配置及详细注释代码(站在新手小白的角度)第三方微信授权登录的实现!!

uniapp微信浏览器H5授权微信登录,UniApp开发H5接入微信登录的全过程,uniapp的H5页面使用微信登录,uniapp H5微信授权登录,H5之微信授权登陆 (uniapp网页版微信授权登录),uni-app开发H5第三方微信授权登录的实现,uniapp如何实现微信授权登录,公众号H5页面接入微信登录流程,uni-app - 最详细 H5 网页接入微信登录功能,提供公众号配置与详细注释示例代码(移动端网页实现点击登录按钮后 调用微信公众号授权登录功能 详细讲解接入流程与详细示例代码)官方最新超级

✅ 精选推荐文章 1万+

302.QoS实现工具之MQC

QoS 技术可以对网络中报文进行分类处理,根据优先级提供不同的差分服务,如何实现这种差分服务呢?我们有一种强大的配置方法 - 模块化 QoS 命令行 MQC(Modular QoS Command-Line)。下面就来介绍一下 MQC。

迷逝 1391

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

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

木牛的博客 1009

甲基化生物信息学分析及批次效应校正全流程

本文系统阐述了DNA甲基化数据分析中的批次效应问题及解决方案。甲基化数据(β值和M值)对实验批次差异高度敏感,可能导致假阳性结果。文章详细介绍了批次效应检测方法(PCA可视化、BEclear定量评分)和校正流程,包括数据预处理、参数化(ComBat-met)与非参数化(BEclear)校正方法,并提供了完整的R代码实现。重点解决了β值有界分布与统计模型假设冲突的问题,为甲基化研究的可靠性提供技术保障。

huanghm88的专栏 107

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

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

linuxheik的专栏 699

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

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

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

linson_zhou的专栏 1068

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

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

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

fatsandwich的专栏 2133

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

关于多进程编程中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的博客 760
上一篇: Linux兴趣小组暑假留校第四次讲座总结
下一篇: 一看就会,一看就懂,快速上手Git
FallingU
博客等级 码龄11年 61粉丝 27原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值