fork介绍,返回值问题,写时拷贝,进程切换,子进程开始执行的位置,子进程的用途

目录

fork

介绍

fork的返回值问题

介绍

fork()时,系统要做什么 

数据是否要独立 

如果共享的话,就会出现问题!

写时拷贝 

引入

介绍

举例(fork返回值)

fork返回的值是什么 

创建失败的原因

子进程执行位置从哪里开始

引入

进程切换

子进程执行的位置

子进程的用途


fork

介绍

  • fork()函数是一个系统调用,用于创建一个新的进程
  • 它会复制当前进程的内容,并在新进程中运行,当前进程是新进程的父进程,从而使父进程和子进程可以并行执行
  • 各自有自己的独立地址空间,但它们可以共享一些资源,如文件描述符
  • 头文件:<unistd.h>

fork的返回值问题

介绍

 

  • 当我们运行起来这个程序时,我们会发现,我们已经成功创建出了子进程(因为有两个pid被打印出来,并且其中一个是另一个的父亲)
  • 但是,我们仔细观察观察,似乎ret这个变量似乎有不同的值
  • 因为我们看到它可以同时执行if 和 else的内容,也就是说,在两个进程中,实际上ret的值是不同的
  • 这是为什么呢?

 

fork()时,系统要做什么 

  • 首先明确: 进程 = 内核数据结构(os来分配) + 进程代码和数据(一般从磁盘中来)

  • 执行fork,也就是创建了一个新的进程,只不过这个新进程有点特殊,数据几乎全部都继承自创建自己的父进程
  • 控制权转移到内核中后(os会为子进程分配空间,提供初始值)
  • 从fork()函数的返回值开始,就开始并行执行两个进程啦

数据是否要独立 

  • 因为进程具有独立性,所以子进程也得有自己的代码和数据
  • 但是我们没有加载内存的过程,它也就没有自己的代码和数据,就可以和父进程共享使用
  • 代码共享没有什么问题,因为不可更改,都是只读
  • 但是!!数据可不能共享,它是可写的!
  • 如果共享的话,就会出现问题!
  • 一般创建子进程就是为了和父进程执行不同的操作
  • 如果其中一个变量一修改,另一个进程也会受到影响的话,未免也太挫了,也不满足独立性
  • 所以!数据必须分离!!

写时拷贝 

引入

虽然数据要分离,但是子进程用不到的那些数据还有必要再拷贝一份吗?

  • 显然是没有的
  • 这样的情况下,共享也是没有问题的
  • (这样的例子可以在c语言中看到,比如两个指针指向同一个常量字符串,编译器也不会傻到开辟两份空间存储内容一样的字符串)
  • 因此,只有将来会被父/子进程写入的数据,才值得被拷贝
介绍
  • 但是,其实os也无法知道哪些数据会被写入,提前拷贝了也不会立马使用(相当于占着茅坑不拉屎)
  • 所以,os选择了写时拷贝技术来将数据分离
举例(fork返回值)
  • 所以前面的fork返回值问题,实际上返回值接收的这一过程就是写入
  • 所以发生了写时拷贝
  • 父子进程这一变量存在两份,但虚拟地址并没有改变,也就导致了我们看到的结果
  • 但是可以通过不同的页表映射,从而找到实际的物理地址

fork返回的值是什么 

虽然我们已经知道了两个进程中的ret不一样,但为什么会不一样呢?

  • 是因为fork()在不同进程中返回了不同的值
  • fork()在父进程中返回子进程的进程pid(该值一般大于0),而在子进程中返回0
  • fork的返回值由os控制
  • 它将子进程的pid返回给父进程,以便父进程可以管理子进程,然后继续下面的代码
  • 子进程返回0,用于区分子进程
  • 如果父进程收到-1,则代表进程创建失败

创建失败的原因

  • 创建内存是需要使用内存资源的
  • 如果当前系统有太多进程,内存资源不足时,os就可能不让你继续创建了
  • 而且作为一个用户,可拥有的进程数是一定的

子进程执行位置从哪里开始

引入

我们其实还会发现,在fork之前的语句,子进程并没有执行:

我们会发现,在fork之前的那句打印只出现了一次,说明子进程是没有执行那个语句的

可以说明 -- 子进程并不是从头开始执行程序的

那子进程从哪里开始执行呢?

进程切换

  • cpu使用进程切换的策略执行语句
  • 并且要保证每个进程下次来的时候,必须从之前的位置继续运行(而不是重新来过,不然前面就白执行了)
  • 所以cpu必须要有对应的寄存器数据(EIP  ,  程序计数器(pc指针)),来记录当前运行进程的执行位置
  • cpu执行指令靠的就是EIP中的地址 (地址+指令长度=下一条指令地址)
  • 每个进程走的时候,带走这份数据,下次来的时候再给寄存器,就可以实现想要的效果啦
  • (寄存器数据也就是进程的上下文数据)

子进程执行的位置

  • 子进程成功创建的时候,恰好为fork该执行return指令的时候
  • 因为当执行到return时,就说明它的主要功能已经实现,也就是子进程已经创建出来了
  • 它里面的pc也就继承自父进程的进度(return的那里),他就认为自己的EIP起始值就是return指令的地址
  • 所以子进程就从return开始执行
  • 也可以通过这个理论,修改子进程的pc值

子进程的用途

就 -- 要么子承父业,要么自己独自发展

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

DNS协议详解

一&#xff1a;DNS协议简介 当我们想要访问百度的时候&#xff0c;我们会输入网址www.baidu.com&#xff0c;而不是直接输入百度的服务器的IP地址去访问&#xff0c;而且我们也不知道百度的服务器的IP地址是多少。为什么我们输入百度的网址就能自动去找到百度的服务器地址呢。这…

SAP-部分字段变更

在SAP中部分字段是可以自行调整的&#xff0c;例如下图 这个字段是客户组1&#xff0c;已经被改成一级经理&#xff0c;现在来操作改回客户组1 首先选择字段点击F1-技术信息-数据元素&#xff08;双击&#xff09; . . 保存&#xff0c;返回&#xff0c;激活&#xff0c;返…

【element优化经验】怎么让element-ui中表单多语言切换排版不乱

目录 前言&#xff1a; 痛点&#xff1a; 1.左对齐&#xff0c;右对齐在中文和外语情况下字数不同&#xff0c;固定宽度会使名称换行&#xff0c;不在整行对齐&#xff0c;影响美观。 2.如果名称和输入框不在一行&#xff0c;会使页面越来越长 3.label-width值给变量&#…

【图论】关键路径求法c++

代码结构如下图&#xff1a; 其中topologicalSort(float**, int, int*, bool*, int, int)用来递归求解拓扑排序&#xff0c;topologicalSort(float**, int*&, int, int, int)传参图的邻接矩阵mat与结点个数n&#xff0c;与一个引用变量数组topo&#xff0c;返回一个布尔值…

C语言数组的距离(ZZULIOJ1200:数组的距离)

题目描述 已知元素从小到大排列的两个数组x[]和y[]&#xff0c; 请写出一个程序算出两个数组彼此之间差的绝对值中最小的一个&#xff0c;这叫做数组的距离 。 输入&#xff1a;第一行为两个整数m, n(1≤m, n≤1000)&#xff0c;分别代表数组f[], g[]的长度。第二行有m个元素&a…

为什么你的自动化测试无法落地

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

[Android]使用Git将项目提交到GitHub

如果你的Mac还没有安装Git&#xff0c;你可以通过Homebrew来安装它&#xff1a; brew install git 方式一&#xff1a;终端管理 1.创建本地Git仓库 在项目的根目录下&#xff0c;打开终端&#xff08;Terminal&#xff09;并执行以下命令来初始化一个新的Git仓库&#xff1…

Centos7安装Cesi(Supervisor集中管理工具)

Background CeSi 是 Supervisor 官方推荐的集中化管理 Supervisor 实例的 Web UI&#xff0c;该工具是用 Python 编写&#xff0c;基于 Flask Web 框架 。Superviosr 自带的 Web UI 不支持跨机器管理Supervisor 进程&#xff0c;功能比较简单&#xff0c;通过 CeSi 可以集中管理…

Python 如何开发出RESTful Web接口,DRF框架助力灵活实现!

Django Rest Framework&#xff08;DRF&#xff09;是构建强大且灵活的Web API的优秀工具。它基于Django&#xff0c;提供了一套用于构建Web API的组件和工具&#xff0c;简化了API开发过程&#xff0c;同时保留了Django的优雅和强大。 一、Web应用模式 在开发Web应用时&…

Jquery ajax 同步阻塞引起的UI线程阻塞的坑(loading图片显示不出来 )

Jquery ajax 同步阻塞引起的UI线程阻塞的坑&#xff08;loading图片显示不出来&#xff0c;layer.load延迟&#xff09;jax重新获取数据刷新页面功能&#xff0c;因为ajax属于耗时操作&#xff0c;想在获取数据且加载页面时显示加载遮罩层&#xff0c;结果发现了ajax的好多坑。…

使用Wireshark提取流量中图片方法

0.前言 记得一次CTF当中有一题是给了一个pcapng格式的流量包&#xff0c;flag好像在某个响应中的图片里。比较简单&#xff0c;后来也遇到过类似的情况&#xff0c;所以总结和记录一下使用Wireshark提取图片的方法。 提取的前提是HTTP协议&#xff0c;至于HTTPS的协议需要导入服…