进程及进程地址空间

进程理解

概念:进程是程序的一个执行实例,其实启动一个程序(静态)本质就是启动了一个进程(动态),进程具有独立性。

用户角度:进程=代码+数据+内核数据结构(PCB结构体+页表+操作系统分配的地址空间)。

内核角度:承担分配系统资源的基本实体。

        Linux是可以同时加载多个程序的,即Linux是可能存在大量进程的,因此必须要对大量的进程进行管理,而管理的方式便是“先描述,再组织”。为了描述进程,每个进程都有一个属于自己的PCB结构体,全称process_control_block,也称进程控制块。在不同的操作系统中,PCB的具体名字是不同的,Linux中为struct task_struct{ };它会被加载到内存中,并且携带着进程的信息。

task_struct内容分类

        将进程的具体信息抽象成为task_struct之后,对进程的管理就变成了对进程PCB结构体链表的增删查改。操作系统和CPU运行某个进程的本质就是从运行队列中挑选一个task_struct来执行该进程对应的代码。

创建进程

        Linux中通过fork()系统调用从已存在进程中创建一个新进程。新进程为子进程,而原进程为父进程。fork()之后要用if分流,子进程返回0,父进程返回子进程的pid,失败时返回-1。pid就是进程标识符。

fork常规用法

一个父进程希望复制自己,使父子进程同时执行不同的代码段。例如,父进程等待客户端请求,生成子 进程来处理请求。 一个进程要执行一个不同的程序。例如子进程从fork返回后,调用exec函数。

fork调用失败的原因

系统中有太多的进程

实际用户的进程数超过了限制

        进程调用fork,当控制转移到内核中的fork代码后,内核做如下几件事:

        1、分配新的内存块和内核数据结构给子进程。

        2、将父进程部分数据结构内容拷贝至子进程。

        3、添加子进程到系统进程列表当中。

        4、fork返回,开始调度器调度。

        fork之后,系统内多了一个进程,要给子进程创建对应的内核数据结构,必须子进程自己独有,因为进程具有独立性。理论上,子进程也要有自己的代码和数据,可是一般而言,创建子进程的并没有加载过程,因此,子进程只能“使用”父进程的代码和数据。具体“使用”的策略是代码部分为只读,对应数据部分为写时拷贝。

具体原因

1、当真正使用时再进行对应资源分配,是高效使用内存的一种表现。

2、操作系统无法在代码执行前预知哪些空间会被拷贝。

具体例子:

#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>
#include<iostream>
int main()
{pid_t id = fork();if(id == 0){std:: cout << "我是子进程" << "pid为: " << getpid() << std::endl;}else if(id < 0){//创建子进程失败perror("fork");exit(-1);//退出码设置为-1;}else{//父进程waitpid(id, nullptr, 0);//等待子进程退出,父进程回收子进程资源 std:: cout << "我是父进程" << "pid为: " << getpid() << std::endl;}return 0;
}

        此处父进程和子进程的调度顺序并不是绝对的,而是要看操作系统的调度策略。

进程状态

概念:进程状态分为新建状态,运行状态,阻塞状态,挂起状态和退出状态。

        首先,操作系统管理的资源一定是各种各样的,不仅仅是CPU资源,还有诸如网卡,显卡,磁盘等其他设备,因此除了运行队列之外,系统中还存在其他进行管理资源等待与分配的队列。

 运行状态:并不仅仅是该进程正在运行就叫做运行态,而是task_struct在对应的运行队列中排队,这个task_struct对应的进程状态就叫做运行态。

阻塞状态:处于阻塞状态的进程,一定是处于某种资源未就绪的状态,因此等待非CPU资源就绪的进程所处的状态就称为阻塞状态。

挂起状态:内存快不足时,操作系统会执行一种策略,将长时间不执行的进程代码和数据换出到磁盘中,用来缓解内存使用紧张的问题。被换出的进程只有PCB在内存中。此时该进程的状态就称为挂起。

具体Linux下的进程状态

僵尸进程:进程已经退出,但是还不允许被操作系统释放,处于一个被检测的状态的进程称为僵尸进程。

具体例子:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{pid_t id = fork();if(id < 0){//创建子进程失败perror("fork error");return -1;}else if(id > 0){//father processint cnt = 0;while(cnt < 10){printf("我是父进程, pid:%d, ppid:%d\n", getpid(), getppid());++cnt;}}else{//child processint cnt = 0;while(cnt < 5){printf("我是子进程, pid:%d, ppid:%d\n", getpid(), getppid());++cnt;}}return 0;
}

        上面的例子中,子进程先退出,父进程后退出,在子进程退出而父进程未退出的时间段内,该子进程为僵尸进程。

为什么会有僵尸进程的原因

        本质是为了维持该状态,以便于父进程结束后及时回收该系统资源,但维持该状态就意味着要维持该僵尸进程的PCB,虽然代码和数据可以被释放,但PCB不行,所以会存在系统资源层面的内存泄露问题。

        要解决僵尸进程的问题,要通过进程等待系列的系统接口wait和waitpid。

孤儿进程

概念:父进程提前退出,子进程并没有退出,此时的子进程称为孤儿进程。该孤儿进程会被1号进程领养,作为该进程的父进程来回收该子进程的资源,避免系统资源层面的内存泄露。1号进程就是bash。

具体例子:

#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
int main()
{pid_t id = fork();if(id < 0){perror("fork");//子进程创建失败}else if(0 == id){//child processint cnt = 0;while(cnt < 5){printf("我是子进程  pid: %d, ppid:%d\n", getpid(), getppid());sleep(1);++cnt;}}else{//father processint cnt = 0;while(cnt < 2){printf("我是父进程  pid:%d, ppid:%d\n", getpid(), getppid());sleep(1);++cnt;}}return 0;
}

上面例子中,父进程先退出,在父进程退出到子进程退出的时间段内,该子进程称为孤儿进程。

进程地址空间

概念:进程地址空间是操作系统为了管理实际内存而设计的一种数据结构,是一种虚拟地址。每个进程在被创建时,除了进程PCB之外,在合适的时候,操作系统也会为该进程申请对应的进程地址空间和页表,通过填写页表,维护虚拟地址和真实物理地址的关系。

设计进程地址空间的原因及好处

1、进程直接访问物理内存是不安全的,通过进程地址空间,凡是非法的访问或者映射,操作系统都会识别并终止该进程。有效的保护了物理内存和物理内存中的合法数据,因为地址空间和页表是操作系统创建和维护的,凡是向使用地址空间和页表进行映射,也一定会在操作系统的监管之下进行访问。

2、因为有地址空间的存在,因为有页表的映射存在,物理内存中可以对数据进行任意位置的加载,原本物理内存中的几乎所有数据和代码在内存中是乱序的,有了地址空间和页表后,在进程视角,所有的内存分布都可以是有序的,所以地址空间+页表的存在可以将内存分布有序化。

3、进程要访问的物理内存中的数据和代码,可能目前并没有在物理内存中,同样的,也可以让不同的进程映射到不同的物理内存,通过地址空间+页表的方式实现了进程的独立性。页表映射的时候,不仅仅可以映射物理内存,磁盘中的位置也是可以映射的。

4、完成了内存管理和进程管理模块的解耦合,本质上,因为地址空间的存在,上层申请空间其实是在地址空间上申请的,物理内存可以甚至一个字节都不给你,只有当真正进行对物理地址空间访问的时候,才执行内存的相关管理算法,帮你申请内存,构建页表映射关系,提高内存整体使用效率。

小问题

在fork后,返回值有两个,是因为两个进程分别return,子进程和父进程返回的值看似存到一个变量中,实际在页表映射时,映射的是不同的物理地址,也就是说,虚拟地址可以显示的一样,但实际上页表映射的物理空间是不一样的。

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

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

相关文章

UI5:面向企业级应用的JavaScript框架

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

T31开发笔记: 移动侦测

若该文为原创文章&#xff0c;转载请注明原文出处。 最近在测试创安源IPC时发现摄像头的视频流有移动侦测功能 &#xff0c;拆解后发现使用的是T31,刚好手头上有淘宝买50多点的T31摄像头&#xff0c;就自己现在了个简易DEMO测试一下。 一、硬件和开发环境 1、硬件&#xff1a;…

Linux学习之路 -- 进程篇 -- 进程地址空间

目录 一、背景介绍 二、进程地址空间 1.看现象 2.先简单描述一下地址空间&#xff08;地址空间全在操作系统的内部&#xff09; 3.地址空间详细一点的描述 4.进程地址空间里面的内容&#xff08;部分&#xff09; 三、进程地址空间的转换机制 1.页表 2.进程地址空间和页…

YoloV8改进策略:卷积改进|DOConv轻量卷积,即插即用|适用各种场景

摘要 本文使用DOConv卷积&#xff0c;替换YoloV8的常规卷积&#xff0c;轻量高效&#xff0c;即插即用&#xff01;改进方法非常简单。 DO-Conv&#xff08;Depthwise Over-parameterized Convolutional Layer&#xff09;是一种深度过参数化的卷积层&#xff0c;用于提高卷…

【Web】HNCTF 2022 题解(全)

目录 Week1 Interesting_include 2048 easy_html What is Web Interesting_http easy_upload Week2 ez_SSTI easy_include ez_ssrf Canyource easy_unser easy_sql ohmywordpress Week3 ssssti Fun_php ez_phar QAQ_1inclu4e logjjjjlogjjjj …

嵌入式学习58-ARM7(自动设备号和混杂设备)

知识零碎&#xff1a; 头文件查找&#xff1a; /arm/路径下的头文件 linux驱动程序的编写&#xff0c;编译&#xff0c;运行过程 -------------------------------------------------------------------------------------------------------------------------------- 1.…

密钥密码学(一)

原文&#xff1a;annas-archive.org/md5/b5abcf9a07e32fc6f42b907f001224a1 译者&#xff1a;飞龙 协议&#xff1a;CC BY-NC-SA 4.0 前言 序言 从秘密解码环到政府政策声明&#xff0c;隐藏和发现信息的挑战长期以来一直吸引着智慧。密码学是一个引人入胜的主题&#xff0c;…

HCIA-Datacom实验_05_实验三:OSPF路由协议基础实验

一、实验拓扑 二、实验步骤 (一)修改设备名称、配置接口IP、Loopback口IP R1 R2 R3 (二)配置OSPF R1 R2 R3 (三)配置认证 R1 R2 R3

队列常规使用

文章目录 一、同步互斥改进方法二、队列实现同步三、队列实现互斥总结 一、同步互斥改进方法 在上一章同步互斥中&#xff0c;我们有两个实验。 同步实验&#xff1a; 我们创建了两个任务&#xff0c;任务1循环遍历一个比较大的数字&#xff0c;遍历完成后设置标志位置1。任务…

【极速前进】20240422:预训练RHO-1、合成数据CodecLM、网页到HTML数据集、MLLM消融实验MM1、Branch-Train-Mix

一、RHO-1&#xff1a;不是所有的token都是必须的 论文地址&#xff1a;https://arxiv.org/pdf/2404.07965.pdf 1. 不是所有token均相等&#xff1a;token损失值的训练动态。 ​ 使用来自OpenWebMath的15B token来持续预训练Tinyllama-1B&#xff0c;每1B token保存一个che…

ONLYOFFICE 协作空间 2.5 现已发布:公共房间改进、用户群组、储存空间管理、嵌入预设等更新

本次更新优化了 ONLYOFFICE 协作空间的多项功能&#xff0c;让您的工作能更加轻松、高效。阅读下文了解所有更新。 关于 ONLYOFFICE 协作空间 ONLYOFFICE 协作空间是一个文档办公&协作平台&#xff0c;自带文档编辑器&#xff0c;提供一整套用于文档储存、共享和协作的工具…

微电子领域常见概念(六)化学键合

微电子领域常见概念&#xff08;六&#xff09;化学键合 化学键合是化学中一个非常基础且重要的概念&#xff0c;它描述了原子之间通过电子的相互作用形成的连接。可以进行以下分类&#xff1a; 1. 离子键合&#xff08;Ionic Bonding&#xff09; • 定义&#xff1a;离子键合…