【操作系统和计网从入门到深入】(二)进程

前言

在这里插入图片描述
这个专栏其实是博主在复习操作系统和计算机网络时候的笔记,所以如果是博主比较熟悉的知识点,博主可能就直接跳过了,但是所有重要的知识点,在这个专栏里面都会提到!而且我也一定会保证这个专栏知识点的完整性,大家可以放心订阅~

进程相关概念

文章目录

  • 前言
  • 进程相关概念
    • 1. 基本理念
    • 2. 进程的描述
      • 2.1 为什么需要pcb
      • 2.2 什么是pcb
    • 3. 查看进程
    • 4. 在程序中pid
    • 5. 父进程是什么
    • 6. 创建子进程
        • 创建进程的时候,OS要干嘛?
        • cpu的运行队列 run_queue
    • 7. 进程状态
    • 8. 状态优先级
    • 9. 环境变量
    • 10. 地址空间
      • 10.1 什么是地址空间
      • 10.2 地址空间是如何设计的
      • 10.3 扩展内容(比较难理解)
      • 10.4 为什么要有地址空间的三个理由
        • 10.4.1 理由一
        • 10.4.2 理由二
        • 10.4.3 理由三
      • 10.5 重新理解挂起

1. 基本理念

重要理论:先组织再描述:struct结构体

在操作系统内部,一定存在大量的数据结构和算法

2. 进程的描述

2.1 为什么需要pcb

为了描述每一个进程,Linux内核会给每一个进程创建一个结构体:PCB

PCB结构体包含了该进程的属性!

struct PCB
{
  	// 属性数据,进程全部的属性数据,如pid
  	// ... 
  	struct PCB* next;
    struct PCB* prev;
};

对进程的管理,变成了对进程PCB结构体链表的增删查改!

什么是进程:进程=对应的代码数据+进程对应的PCB结构体

2.2 什么是pcb

在linux中,叫task_struct

里面会有这些内容。

是一个双链表!

3. 查看进程

表头也可以带上

ps axj | head -1 && ps axj | grep myproc

top命令也可以查看进程

Linux系统下存在一个目录记录进程的信息。

/proc # 这个目录下都是进程的信息

在这个目录下,都是进程的属性。

我们可以看下里面的信息。

事实上,/proc目录是动态的,多一个进程就会多一个目录,少一个进程就会少一个目录。

4. 在程序中pid

在程序中如何获得pid呢?

getpid() // 这是我们人生中第一个系统调用接口

5. 父进程是什么

ps axj 一下,发现父进程是bash

bash是shell命令行外壳程序

很熟悉了这些。

6. 创建子进程

fork

fork()

返回值:

  • fork失败,返回-1
  • fork成功:给父进程返回子进程的pid,给子进程返回0

为什么会有两个返回值呢?不是只能返回一个吗?后面再说。

我们简单写一个代码。

第二个为什么被执行了两次?

因为不加判断,父进程和子进程都会执行。

复习到后面就会知道,创建子进程的时候,这份代码是被复制了的!

所以第二句打印语句,父子进程共享。

我们加上一个判断,就能把子进程和父进程分开来!

创建进程的时候,OS要干嘛?

本质,创建一个新的task_struct,然后这里里面的字段,有一些是复制父进程的,有一些事自己的。

cpu的运行队列 run_queue

进程调度本质上就是调度程序,在run_queue里面挑选一个task_struct来执行!

但是这个运行队列也不是按一般顺序的,这个是调度程序决定的!

7. 进程状态

具体可以看博客。

进程状态|操作系统|什么是pcb|什么是僵尸进程 |什么是孤儿进程 【超详细的图文解释】【Linux OS】_pcb结构体-CSDN博客

后台运行一个进程

./test & 

8. 状态优先级

状态优先级 = 老的优先级 + nice值

PRI就是优先级,越小越先执行

NI就是nice值

9. 环境变量

比较熟了,不再赘述。

要改可以用export

但是要记得把之前的带上

注意,环境变量的组织方式是一个字符指针数组

可以用程序打印所有环境变量。

第一种获取方式:

第二种获取方式:

略。不常用,其实第一种也不常用,第三种才常用。

main函数的第三个参数,也就是环境变量参数,是从哪里来的?

一般都是父进程中继承下来的

10. 地址空间

10.1 什么是地址空间

我们在所有的语言里面提到的地址的概念,本质上都是一个虚拟地址,而不是物理地址。

页表映射,现在只知道大概,不知道细节,所以这一节简单复习一下。

这个结构是可以用代码进行验证的。

// 验证地址空间的栈结构
int g_unval;     // 未初始化的全局变量
int g_val = 100; // 已经初始化的全局变量
int main(int argc, char *argv[], char *env[])
{
    printf("code addr: %p\n", main);              // 代码块位置
    printf("init global addr: %p\n", &g_val);     // 初始化全局变量
    printf("uninit global addr: %p\n", &g_unval); // 未初始化全局变量

    char *heap_memory = (char *)malloc(10);
    printf("heap addr: %p\n", heap_memory); // 堆上的空间

    printf("stack addr: %p\n", &heap_memory); // 栈上的空间

    for (int i = 0; i < argc; i++)
    {
        printf("argv[%d]: %p\n", i, argv[i]);
    }
    for (int i = 0; env[i]; i++)
    {
        printf("env[%d]: %p\n", i, env[i]);
    }
    return 0;
}

10.2 地址空间是如何设计的

其实就是给各个进程画饼。

先描述后组织!

如果我们可以直接访问物理内存的话,其实是特别不安全的。

所以我们构建了映射机制。

如何理解地址的划分? — 其实就是一个简单的struct结构体就行了。

struct myroom
{
  	int __start;
  	int __end;
};

其实地址空间的各个区域,也是通过这个方式进行划分的。

struct addr_room {
    int code_start; int code_end;
    int init_start; int init_end;
    int uninit_start; int uninit_end;
    int heap_start; int heap_end; 
    //...其他属性
}

现在我们又可以知道,task_struct里面的又一个字段了! — mm_struct* mm

地址空间和页表(用户级)是每一个进程都私有一份的,只要保证,每一个进程的页表,映射的是物理内存的不同区域,我们就能做到,进程之间不会互相干扰进程的独立性。

回答一个遗留问题:return两个不同的值是怎么回事?

Return会被执行两次

Return的本质不就是对值进行写入吗? – 此时发生了写时拷贝!

所以两个进程各自其实在物理内存中,有属于自己的变量空间!只不过是在用户层面用同一个变量(虚拟地址!)来标识了!

10.3 扩展内容(比较难理解)

10.4 为什么要有地址空间的三个理由

10.4.1 理由一

可以有效保护物理内存,禁止非法映射

10.4.2 理由二

因为有地址空间的存在,因为有页表的映射,我们的物理内存中,是不是可以对未来的数据进行任意位置的加载?

当然可以!

首先,物理内存的分配,可以和进程管理完全解耦!

所以我们newmalloc的时候都是申请虚拟地址空间。

紧接着一个问题:如果我们申请了物理空间,但是又不马上使用,是不是造成了空间的浪费呢?当然是的!

所以事实上,OS是非常聪明的,你虽然malloc了100个字节,但是我可以一个都不给你!

而你去访问或者使用这100个字节的事哦呼,下面的物理地址空间的相关管理算法才把这个100字节分给你,再让你访问!但是你上层是0感知的!

这个叫做延迟分配的策略!

那么,OS是如何知道,一些内存空间虽然在虚拟上给了,但是物理上还 没给呢?这里有个技术叫做 —— 缺页中断!(后面我们再完善这个概念)

10.4.3 理由三

因为物理内存中理论上可以任意位置加载,那么是不是物理内存中的几乎所有的数据和代码在内存是乱序的?

但是,因为页表的存在,它可以进行映射!

那么是不是在进程视角所有的内存分布, 都可以是有序的?

是的! 地址空间+页表的存在可以将内存的分布有序化!

比如说:

我一个进程看到的,是一个连续的0-ffff的地址,但是事实上,在物理上,这个可能是分散的,分块的哦!

但是我进程需要知道这些吗?根本不需要care,我只知道,我用的是0-ffff的连续的地址就行了,底层是怎么样的,我根本不需要知道!

10.5 重新理解挂起

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何使用GaussDB创建外表(FOREIGN TABLE)

目录 一、前言 二、创建外表的特点 二、GaussDB创建外表访问外部数据库表&#xff08;示例&#xff09; 1、创建外表 2、FAQ&#xff1a;CREATE USER MAPPING错误 三、GaussDB创建外表映射数据文件&#xff08;示例&#xff09; 1、创建数据文件 2、创建外表 3、FAQ&a…

AI 种菜革命:农业科学家们的探索/《流浪地球》导演感受到AI的威胁,《浪球3》也遇灵感洗礼 | 魔法半周报

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件&#x1f525;&#xff0c;更新AIGC的最新动态&#xff0c;生成相应的魔法简报&#xff0c;节省阅读时间&#x1f47b; &#x1f525; 资讯预览 AI 种菜革命&#xff1a;农业科学家们的探索 《流浪地球》导演感受到AI的威…

打包CSS

接上一个打包HTML继续进行CSS的打包 1.在之前的文件夹里的src文件夹创建一个css文件 2.在浏览器打开webpack——>中文文档——>指南——>管理资源——>加载CSS 3.复制第一句代码到终端 4.复制下图代码到webpack.config.js脚本的plugins&#xff1a;[.....]内容下…

vue3使用mars3d实现地图轮播高亮,且每个区域颜色不一样

效果图(珙县就是轮播高亮的效果) 思路:初始化一张完整的地图&#xff0c;然后定时器去挨个生成每个县上的地图&#xff0c;并且覆盖在原来的位置&#xff0c;每到一定的时间&#xff0c;就清除之前生成高亮图并且生成下一张高亮图 如何引入地图 上篇文章已详细发过 略 父组…

做数据分析为何要学统计学(5)——什么问题适合使用卡方检验?

卡方检验作为一种非常著名的非参数检验方法&#xff08;不受总体分布因素的限制&#xff09;&#xff0c;在工程试验、临床试验、社会调查等领域被广泛应用。但是也正是因为使用的便捷性&#xff0c;造成时常被误用。本文参阅相关的文献&#xff0c;对卡方检验的适用性进行粗浅…

瑞萨RZ/G2L核心板Linux Log目录文件详解

为了排除系统问题&#xff0c;监控系统健康状况以及了解系统与应用程序的交互方式&#xff0c;我们需要了解各log文件的作用&#xff0c;以G2L中yocto文件系统为例&#xff0c;在系统/var/log/目录下会存放记录系统中各个部分的log文件作用如下&#xff1a; 1. 文件详情 下图…

k8s详细教程(一)

—————————————————————————————————————————————— 博主介绍&#xff1a;Java领域优质创作者,博客之星城市赛道TOP20、专注于前端流行技术框架、Java后端技术领域、项目实战运维以及GIS地理信息领域。 &#x1f345;文末获取源码…

Docker安装与使用

Docker 1.初识Docker Docker如何解决大型项目依赖关系复杂&#xff0c;不同组件依赖的兼容性问题&#xff1f; Docker允许开发中将应用、依赖、函数库、配置一起打包&#xff0c;形成可移植镜像Docker应用运行在容器中&#xff0c;使用沙箱机制&#xff0c;相互隔离 Docker…

2023/12/11 作业

1.思维导图 2.作业 成果&#xff1a; 第一个头文件 #ifndef TEST3GET_H #define TEST3GET_H #include <QWidget> #include<QMessageBox> QT_BEGIN_NAMESPACE namespace Ui { class test3get; } QT_END_NAMESPACE class test3get : public QWidget { Q_OBJE…

人工智能_机器学习063_SVR支持向量机_回归拟合天猫双十一销量方程---人工智能工作笔记0103

之前我们用线性回归做过天猫双十一销量预测的数据,现在我们再来用SVR支持向量机来做一下 首先上面是给出了销量,对应2009年到2019年的,销售额 可以看到: X=np.arange(2009,2020)-2008 统一减去2008的话看起来数据比较简单了 y=np.array([0.5,9.36,52,191,350,571,912,1207,1…

uniCloud(二) 使用数据库、前端展示数据

一、在云服务空间的云数据库中新建一张表 &#xff08;1&#xff09;它有两种方式&#xff0c;我暂时手动创建一张表 &#xff08;2&#xff09;修改表结构&#xff1a;权限read为true &#xff08;3&#xff09;添加数据记录 注意&#xff1a;需要一条一条的加入 二、在前端…

PR快闪模板|简约时尚快节奏开场视频PR模板剪辑素材

这是一款Premiere Pro快闪模板&#xff0c;简约时尚快节奏开场视频 pr模板剪辑素材&#xff0c;用于以独创的方式创建明亮的介绍、时尚的开场白或模特展示。 Premiere Pro CC21及以上&#xff0c;即使是初学者也可以轻松使用&#xff0c;包含视频教程。 来自PR模板网&#xff1…

【Proteus仿真】【51单片机】定时智能插座开关

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用Proteus8仿真51单片机控制器&#xff0c;使LCD1602液晶&#xff0c;DS18B20温度传感器、按键、蜂鸣器、继电器开关、HC05蓝牙模块等。 主要功能&#xff1a; 系统运行后&#xff0c;LCD1602显示…

leetcode 904. 水果成篮(优质解法)

代码&#xff1a; class Solution {public int totalFruit(int[] fruits) {int lengthfruits.length;int []fruitNumsnew int[length1]; //用于记录各个种类摘了多少个水果int count0; //用于记录当前采摘了几种水果int sum0; //用于记录当前共摘了多少水果for(int left0…

jupyter报错KeyError: ‘icosapent‘

指的是未找到关键词 代码想在一个pkl文件里找到关键词对应的值&#xff0c;然后报了这个错 尝试直接双击pkl文件&#xff0c;显示&#xff1a; 这个意思不是说这个文件保存失败&#xff0c;也不是说这个文件是坏的&#xff0c;而是jupyter无法读取这个格式。 换成pycharm运行…

TypeScript 常用高级类型

目录 前言&#xff1a; TypeScript 常用高级类型 基本概念 高级类型 1. 交叉类型&#xff08;Intersection Types&#xff09; 2. 联合类型&#xff08;Union Types&#xff09; 3. 映射类型&#xff08;Mapped Types&#xff09; 4. 条件类型&#xff08;Conditional…

PyQt---基本界面设计【附代码】

Qt是GUI开发中的一个工具&#xff0c;可以根据用户需求进行程序界面的开发。Qt的开发有C版的和python版的&#xff0c;不论你有哪种编程语言的基础都很好上手学习。PyQt5是Qt框架的Python语言实现&#xff0c;也是本文将要介绍的&#xff0c;并将会建立一个PyQt专栏不断更新供大…

解决亚马逊,速卖通,eBay买家账号关联问题,提高下单成功率

做自养号测评、补单首先要解决的就是安全性的问题&#xff0c;如果安全性解决的不了的话&#xff0c;其他的都不要再提了 让我们了解一下市面上的IP及可能遇到的问题。 目前&#xff0c;常见的IP包括luminati、googelfi、922、TM流量卡和Rola&#xff0c;Rrocks专线等。主要问…

在做题中学习(31):电话号码的字母组合(全排列)

17. 电话号码的字母组合 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a;既然要排列组合&#xff0c;就得先根据数字字符取出来 所以先定义一个string类的数组通过下标取到每个数字对应的映射。 string _numsTostr[10]{"","","abc"…

医学多模态模型总结(一)

概念 医学多模态大模型是指利用多种不同的医学数据源和模型&#xff0c;通过深度学习和人工智能技术&#xff0c;构建一个综合性的大型模型&#xff0c;以实现更加准确和全面的医学数据分析和预测。 这种模型可以同时处理多种医学数据类型&#xff0c;如医学图像、病历文本、…
最新文章