【Linux】浅谈冯诺依曼和进程
一、冯诺依曼体系结构

冯诺依曼由 输入设备、输出设备、运算器、控制器、存储器 五部分组成。
冯诺依曼的设计特点
-
二进制表示
所有数据(包括程序指令)均以二进制形式存储和运算,简化了硬件逻辑设计,提高了可靠性。 -
存储程序原理 程序与数据共同存储于同一存储器中,且程序可像数据一样被修改。
-
顺序执行机制 指令按线性顺序逐条执行,由程序计数器(PC)控制执行流程。
-
指令结构 每条指令由操作码(定义操作类型)和地址码(指定操作数位置)组成。
冯诺依曼体系结构的作用
引言: 外设 和 CPU 读取速度完全不一样,如果 外设 和 CPU 直接进行数据交互,就会导致 CPU 读取速度非常缓慢。但 冯诺依曼体系结构 就解决了这种问题,那它是怎么解决的呢?
- 内存作为缓冲区
冯·诺依曼体系结构将内存作为CPU和外设之间的缓冲区。外设将数据写入内存,CPU再从内存读取数据进行处理。这种设计解决了CPU与外设之间速度不匹配的问题。例如,外设(如硬盘)的读写速度远低于CPU,通过内存作为中间存储,可以避免CPU长时间等待外设完成操作。 - 中断机制
冯·诺依曼体系结构引入了中断机制,以优化CPU与外设之间的交互。外设在完成数据写入内存后,会发送中断信号通知CPU。CPU在收到中断信号后,再读取内存中的数据进行处理。这种方式避免了CPU轮询外设状态的低效操作,使得CPU可以将更多时间用于执行其他任务。 - 数据传输的统一性
在冯·诺依曼体系结构中,所有数据(包括程序指令和外设数据)都通过内存进行交互。这种统一的数据流动模式简化了硬件设计,使得CPU只需要支持对内存的读写操作,而无需直接处理多种外设协议。 - 存储分级
冯·诺依曼体系结构通过存储分级(如寄存器、缓存、内存、外存)来优化数据访问速度。内存作为中间层,其访问速度远高于外设,但低于CPU缓存和寄存器。通过这种分级设计,数据可以按需在不同存储层级之间流动,从而提高整体效率。 - 操作系统与驱动程序的支持
操作系统通过驱动程序将外设的复杂操作抽象成统一的接口,进一步优化了CPU与外设之间的数据交互。驱动程序可以动态更新,以支持新功能,而无需修改硬件。
二、操作系统(Operator System)
概念
操作系统(Operating System,简称OS) 是管理计算机硬件与软件资源的系统软件。它提供用户接口和资源分配,是计算机系统中最基本的系统软件,任何计算机系统都包含一个基本的程序集合,统称为 操作系统(OS) 。
简单来讲, 操作系统 包含 :
- 内核(进程管理、内存管理、文件管理、驱动管理)
- 其他程序 (函数库、shell程序等)
设计OS的目的
- 对下,与硬件交互,管理所有软硬件资源
- 对上,为用户程序提供一个良好的运行环境

OS如何管理软、硬件
OS 是怎么管理软、硬件的呢?,简单6个字就可以总结:先描述,再组织
- 先描述 :描述起来,用 struct 结构体来描述
- 再组织 :通过数据结构报 struct 结构体组织起来,用链表或其他数据结构(队列、哈希等)组织起来
进程
上面讲了 OS 是怎么将软硬件资源管理起来的,那么对于进程也是再这样吗?答案是肯定的
概念
- 进程信息被放在一个叫做 进程控制块 的数据结构中,可以理解为描述进程属性的结构体
- 课本上称之为 PCB (process control block), Linux 操作系统下的PCB叫做 task_struct,是一种结构体
task_struct (描述进程)
task_struct 中的进程属性很多,我在这里描述其中的一部分:
3. 标识符:描述本进程的唯一标识符,用来区别其他进程
4. 状态:任务状态,退出代码,退出信号等
5. 优先级:用来描述进程被调度的先后的数字,数字小的优先级高,数字大的优先级低,和成绩排名有异曲同工之妙
6. 程序技术器(PC):表示程序中即将执行的下一条指令的地址
7. 内存指针:包括程序代码和进程相关数据的指针,还有和其他进程共享内存块的指针
8. 上下文数据:进程执行时处理器的寄存器中的数据,主要包括:
CPU寄存器的值:包括程序计数器(PC)、指令寄存器、堆栈指针等。
内存映射信息:进程的虚拟内存空间布局。
进程状态:如运行状态、阻塞状态、就绪状态等。
I/O状态:与进程相关的输入输出设备的状态。
其他系统资源的状态:如文件描述符、信号状态等。
9. I / O状态信息:包含显示的 I / O 请求,分配给进程的 I / O 设备和被进程使用的文件链表
10. 记账信息:可能包括处理器时间总和,使用的时钟数总和,时间限制,记账号的等。
组织进程
PCB 在内核中使用双链表进程链接起来的

查看进程
-
通过 /proc 系统文件夹来查看

-
通过 top 和 ps 这些用户工具来获取进程信息
top:top -p [pid]

ps:ps axj

通过系统调用获取进程标识符
- 获取进程id (PID):
getpid() - 父进程id (PID):
getppid() - 通过手册来查看相关系统调用:
man 2 getpid

通过系统调用fork创建子进程

通过 fork 创建的子进程和父进程共享同一份代码,但数据是各自私有的(写时拷贝)(其中 pid_t 的类型其实是一个有符号整数类型,取了个别名而已,当 fork() 返回值为 0 时就表示子进程,当 fork() 返回值大于0时,表示的就为父进程。)
至于为什么数据各自私一份,有我们通过一个程序就可以看出来
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>int main()
{int val = 0;pid_t id = fork();if(id == 0)//表示子进程{while(1){printf("我是子进程,pid: %d ,ppid: %d, val = %d\n",getpid(),getppid(),val++);sleep(1);}}else//父进程{while(1){printf("我是父进程,pid: %d ,ppid: %d, val = %d\n",getpid(),getppid(),val);sleep(1);}}return 0;
}
程序运行结果:

可以看到父进程和子进程的 val 的值并不是一样的,我们就可以得出父子进程并不共享同一份数据的结论
进程状态
进程状态有很多种:
- R运行状态:并不意味着进程一定在运行中,它表明进程要么在运行中,要么在运行队列中(运行队列用于管理处于“就绪状态”(Ready State)的进程。这些进程已经准备好运行,但正在等待 CPU 时间片分配。当调度器选择一个进程运行时,它会从运行队列中选取一个进程,并将其状态从“就绪”变为“运行”。)
- S睡眠状态:以为着进程在等待事件完成(也叫做可中断睡眠)
注意: 以下有个场景可能让人误会为是 R 状态 ,但其实是 S 状态
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>int main()
{int cnt = 0;while(1){printf("pid: %d,cnt = %d\n",getpid(),cnt++);}return 0;
}~
这里可能很多认为进程的状态是R状态,其实不然,这里的进程状态其实大部分都是S+(+表示是前台进程)状态,为什么呢?因为进程这里大部分时间都在做IO交互,IO的时间是很慢的,所有看不到R状态

表示每隔1秒查看对应名为code进程的信息:while :;do ps axj | head -1 && ps axj | grep code | grep -v grep;sleep 1 ; done


-
D磁盘休眠状态:有时候叫做不可中断状态(不会响应信号),在这个状态等待IO的结束
-
T停止状态:可以通过发送 SIGSTOP 信号来给进程停止 (T)进程。这个被暂停的进程可以通过发送 SIGCOUT 信号让进程继续执行

-
X死亡状态:这是一个返回状态,你不会在任务列表中看到这个状态,因为这是一个瞬时状态,一下就消失了
-
Z僵死状态:是一个比较特殊的状态。当进程退出并且父进程没有读到子进程返回的退出码时,子进程就会除以一个僵死状态。僵死状态会以终止状态保持在进程表中,并且会一直等待父进程读取退出状态代码(通过 kill -9 pid 杀死子进程就可以看到子进程处于僵死状态)

僵死状态危害
没创建一个子进程就需要一个 PCB ,如果父进程创建了很多子进程,而没有去回收就会造成内存资源的浪费
孤儿进程
父进程如果提前退出,子进程就会变成孤儿进程,孤儿进程就会被1号 init 也就是操作系统启动后第一个运行的用户空间程序

进程优先级
基本概念
-
cpu资源分配的先后顺序,就是进程的优先权。
-
优先级高的进程有优先执行权利。

-
UID : 代表执⾏者的⾝份
-
PID : 代表这个进程的代号
-
PPID :代表这个进程是由哪个进程发展衍⽣⽽来的,亦即⽗进程的代号
-
PRI :代表这个进程可被执⾏的优先级,其值越⼩越早被执⾏
-
NI :代表这个进程的nice值(修正优先级数值的)
其中 PRI(new) = PRI(采用默认值80) + nice
更改进程nice值
通过更改进程 nice 来改变进程优先级
用 top 命令来改变进程 nice 值:
- 进入top后按 “r” -> 输入进程PID -> 输入nice值
进程竞争、独立、并行、并发
- 竞争:本质是僧多粥少,系统进程数目众多,而CPU资源只有少量,所以进程之间具有竞争属性,为了更高效的完成任务,更合理竞争相关资源,于是就有了优先级
- 独立:多进程在运行时,需要独享各种资源,进程之间互不干扰,就算一个进程挂掉了,也不影响另一个进程,而如果线程挂掉了,不仅会影响其他进程,可能还会导致进程挂掉。
- 并行:多个进程在多个CPU下同时进行运行
- 并发:多个进程在同一个CPU资源下采用进程切换的方式,在同一段时间之内,让多个进程都得以推进
进程切换
在多任务操作系统中,多个进程会共享有限的 CPU 资源。为了实现高效的资源利用和良好的用户体验,操作系统需要在这些进程之间切换 CPU 的控制权。这种切换通常发生在以下几种情况:
- 时间片用完:在时间片轮转(Round Robin)调度算法中,当一个进程的时间片用完时,操作系统会将 CPU 切换到另一个进程。
进程阻塞:当一个进程因为等待 I/O 操作(如磁盘读写、网络通信)而阻塞时,操作系统会将 CPU 切换到另一个就绪的进程。
更高优先级的进程就绪:当一个更高优先级的进程进入就绪队列时,操作系统可能会抢占当前运行的进程,将 CPU 切换到优先级更高的进程。
系统调用或中断:当进程执行系统调用或发生中断时,操作系统可能会触发进程切换。 - 进程切换的过程
进程切换是一个复杂的过程,涉及到多个步骤,主要包括以下内容:
2.1 保存当前进程的上下文
当操作系统决定切换进程时,首先需要保存当前运行进程的上下文信息。上下文信息包括:
CPU 寄存器的值:如程序计数器(PC)、指令寄存器(IR)、堆栈指针(SP)等。
进程状态:如运行状态、就绪状态或阻塞状态。
内存映射信息:如页表或段表。
I/O 状态:如打开的文件描述符、设备状态等。
这些上下文信息通常被保存在进程控制块(PCB,Process Control Block)中,或者在内核栈中。
2.2 更新进程状态
操作系统会更新当前进程的状态,将其从“运行状态”(Running State)改为“就绪状态”(Ready State)或“阻塞状态”(Blocked State),具体取决于进程为何被切换出去。
2.3 选择下一个要运行的进程
操作系统通过调度器(Scheduler)选择下一个要运行的进程。调度器会根据调度算法(如先来先服务、时间片轮转、优先级调度等)从就绪队列中选择一个进程。
2.4 恢复新进程的上下文
操作系统从新进程的 PCB 或内核栈中恢复其上下文信息,包括:
将寄存器的值恢复到 CPU 寄存器中。
更新内存映射信息。
恢复 I/O 状态。
2.5 将 CPU 控制权交给新进程
操作系统将 CPU 的控制权交给新进程,新进程从上次被中断的地方继续执行。 - 进程切换的开销
进程切换是一个相对昂贵的操作,因为它涉及到大量的上下文保存和恢复工作。每次切换都会消耗一定的 CPU 时间,具体开销包括:
寄存器保存和恢复:保存和恢复 CPU 寄存器的值。
内存映射切换:更新页表或段表。
调度器开销:选择下一个进程的开销。
缓存失效:切换进程可能导致 CPU 缓存失效,新进程需要重新加载数据到缓存中。
因此,操作系统会尽量减少不必要的进程切换,以提高系统性能。 - 示例:进程切换的场景
假设系统中有两个进程 A 和 B,它们共享 CPU 资源。以下是进程切换的一个简单示例:
进程 A 运行:
进程 A 正在 CPU 上运行,执行某些任务。
时间片用完,操作系统决定切换进程。
保存进程 A 的上下文:
操作系统保存进程 A 的寄存器值、内存映射信息等,并将其状态从“运行状态”改为“就绪状态”。
选择进程 B:
调度器从就绪队列中选择进程 B。
恢复进程 B 的上下文:
操作系统恢复进程 B 的寄存器值、内存映射信息等。
进程 B 运行:
进程 B 从上次被中断的地方继续执行。

Linux2.6内核进程O(1)调度队列
LInux源码查看网站
Linux源码官方网站
Linux2.6内核调度队列

活动队列(array[0])
- 时间片还没有结束的所有的进程都会按照优先级放在该队列
- nr_active:总共有多少个运行的进程
- queue[140]:一个元素就是一个进程队列,相同优先级的进程按照 FIFO(先进先出)的规则排队调度,所以数组下标就是优先级
- bitmap[5]:一共140个优先级,用位图就可以提高非空队列的效率,一个整形占32个比特位,数组大小为5,就有5 * 32 = 160 个bit位来表示队列是否为空,大大提高了查找效率

过期队列
- 过期队列上的进程都是时间片耗尽之后的进程
- 活动队列上的进程都被处理完毕以后,就会对过期队列的进程进行时间片重新计算
active 和 expired 指针
- active指针永远指向活动队列
- expired指针永远指向过期队列
- 活动队列中的进程进程会越来越少,过期队列上的进程会越来越多,因为进程时间片到期就会进入过期队列,但在合适的时间交换 active 指针和 expired 指针的内容,即 swap(&active,&expired) ,活动队列就又有了一批新的活动进程
相关文章:
【Linux】浅谈冯诺依曼和进程
一、冯诺依曼体系结构 冯诺依曼由 输入设备、输出设备、运算器、控制器、存储器 五部分组成。 冯诺依曼的设计特点 二进制表示 所有数据(包括程序指令)均以二进制形式存储和运算,简化了硬件逻辑设计,提高了可靠性。 存储程序原理…...
env.development.local 和 env.development 的区别
env.development.local 和 env.development 的区别 区别1、场景2、git管理3、加载策略 思考原因如下 区别 1、场景 env.development: 用于开发环境的环境变量配置env.development.local: 用于存储特定于开发者的本地配置信息 2、git管理 env.development.local 会通过*.loca…...
linux操作系统实战
第一题 创建根目录结构中的所有的普通文件 [rootlocalhost ~]# cd /[rootlocalhost /]# mkdir /text[rootlocalhost /]# cd /text[rootlocalhost text]# mkdir /text/boot /text/root /text/home /text/bin /text/sbin /text/lib /text/lib64 /text/usr /text/opt /text/etc /…...
Python Cookbook-4.1 对象拷贝
任务 想拷贝某对象。不过,当你对一个对象赋值,将其作为参数传递,或者作为结果返回时,Python 通常会使用指向原对象的引用,并不是真正的拷贝。 解决方案 Python 标准库的 copy 模块提供了两个函数来创建拷贝。第一个…...
浅谈时钟启动和Systemlnit函数
时钟是STM32的关键,是整个系统的心脏,时钟如何启动,时钟源如何选择,各个参数如何设置,我们从源码来简单分析一下时钟的启动函数Systemlnit()。 Systemlnit函数简介 我们先来看一下源程序的注释…...
事业单位ABCDE类
1 我刚刚查阅了一下安徽省市直单位报名的表,我这个专业报的岗位大多数是自然科学专技岗。 2 安徽省的岗位大多都限制计算机科学与技术,我这个0854计算机技术能报的岗位十分有限。 而且我没有看到一个岗位只招应届生,显然安徽不保护应届生的…...
Python:函数(一)
python函数相关的知识点 1. 函数定义与调用 定义:使用 def 关键字,后接函数名和参数列表。 def greet(name):"""打印问候语(文档字符串)"""print(f"Hello, {name}!") 调用:…...
MySql学习_基础Sql语句
目录 1.数据库相关概念 2.SQL 2.1 SQL通用语法 2.2 SQL分类 2.3 DDL(数据库定义语言) 2.4 DML(数据操作语言) 2.5 DQL(数据查询语言) 2.6 DCL(数据控制语言) 3. 函数 3.1 字…...
Nginx 生产环境安全配置加固
以下是Nginx生产环境安全配置加固的综合方案,结合多个技术实践和行业标准整理: 一、基础安全防护 1. 隐藏版本信息 在http或server块添加server_tokens off;,避免暴露Nginx版本号。使用headers-more-nginx-module模块彻底移除响应头…...
C#中继承的核心定义
1. 继承的核心定义 继承 是面向对象编程(OOP)的核心特性之一,允许一个类(称为子类/派生类)基于另一个类(称为父类/基类)构建,自动获得父类的成员(字段、属…...
小白学Agent技术[5](Agent框架)
文章目录 Agent框架Single Agent框架BabyAGIAutoGPTHuggingGPTHuggingGPT工作原理说明GPT-EngineerAppAgentOS-Copilot Multi-Agent框架斯坦福虚拟小镇TaskWeaverMetaGPT微软UFOAgentScope现状 常见Agent项目比较概述技术规格和能力实际应用案例开发体验比较ChatChain模式 Agen…...
21.dirsearch:Web 路径扫描工具
一、项目介绍 dirsearch 是一款高效、多线程的 Web 路径扫描工具,专为渗透测试人员和网络安全研究人员设计,用于发现目标网站的隐藏目录、敏感文件及未授权接口。其支持自定义字典、代理配置、请求头伪装等功能,适用于红队渗透、漏洞挖掘及资…...
VSTO(C#)Excel开发4:打印设置
初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github:codetoys,所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的,可以在任何平台上使用。 源码指引:github源…...
设计模式Python版 模板方法模式(上)
文章目录 前言一、模板方法模式二、模板方法模式示例 前言 GOF设计模式分三大类: 创建型模式:关注对象的创建过程,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、原型模式和建造者模式。结构型模式:关注类和对象之间…...
源IP泄露后如何涅槃重生?高可用架构与自动化防御体系设计
一、架构层解决方案 1. 高防代理架构设计 推荐架构: 用户 → CDN(缓存静态资源) → 高防IP(流量清洗) → 源站集群(真实IP隐藏) ↑ Web应用防火墙(WAF) 实施要点&a…...
transformer bert 多头自注意力
输入的(a1,a2,a3,a4)是最终嵌入,是一个(512,768)的矩阵;而a1是一个token,尺寸是768 a1通过wq权重矩阵,经过全连接变换得到查询向量q1;a2通过Wk权重矩阵得到键向量k2;q和k点乘就是值…...
python-leetcode-定长子串中元音的最大数目
1456. 定长子串中元音的最大数目 - 力扣(LeetCode) 可以使用 滑动窗口 方法来解决这个问题。步骤如下: 初始化:计算前 k 个字符中元音字母的个数,作为初始窗口的值。滑动窗口:遍历字符串,每次右…...
Spring Boot + MyBatis-Plus 项目目录结构
以下是一个标准的 Spring Boot MyBatis-Plus 项目目录结构及文件命名规范,包含每个目录和文件的作用说明,适用于中大型项目开发: 项目根目录结构 src/ ├── main/ │ ├── java/ # Java 源代码 │ │ └── com/…...
Python之变量及简单的数据类型
本文来源于《Python从入门到实践》,自己整理以供工作参考 基本内容 print("Hello Python World!")message "Hello Python world!" print(message)message "Helllo Python Crash Course world!" print(message)name "ada lov…...
力扣 Hot 100 刷题记录 - 翻转二叉树
力扣 Hot 100 刷题记录 - 翻转二叉树 题目描述 翻转二叉树 是力扣 Hot 100 中的一道经典题目,题目要求如下: 给你一棵二叉树的根节点 root,翻转这棵二叉树,并返回其根节点。 示例 1: 输入:root [4,2,7…...
力扣215.数组中的第K个最大元素--堆排序法(java)
为了找到数组中第K个最大的元素,我们可以使用堆排序的方法。堆排序的核心是构建一个最大堆,并通过多次交换堆顶元素来找到前K个最大的元素。具体步骤如下: 方法思路 构建最大堆:将输入数组转换为最大堆,使得每个父节…...
MySQL增删改查操作 -- CRUD
个人主页:顾漂亮 目录 1.CRUD简介 2.Create新增 使用示例: 注意点: 3.Retrieve检索 使用示例: 注意点: 4.where条件查询 前置知识:-- 运算符 比较运算符 使用示例: 注意点…...
【算法day9】回文数-给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。
回文数 给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false 。 回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。 例如,121 是回文&#…...
RSA混合加密RSA混合加密
RSA混合加密是一种结合非对称加密(RSA)和对称加密(AES)的技术,通过两者的优势互补,实现高效且安全的数据传输。以下是详细解释和示例: RSA混合加密的核心原理 非对称加密(RSA&#x…...
蛋白质功能预测论文阅读记录2025(DPFunc、ProtCLIP)
前言 最近研究到瓶颈了,怎么优化都提升不了,遂开始看点最新的论文。 DPFunc 2025.1.2 Nature Communication 中南大学 论文地址:DPFunc: accurately predicting protein function via deep learning with domain-guided structure inform…...
Linux网络套接字编程——UDP服务器
Linux网络套接字编程——创建并绑定-CSDN博客 前面已经介绍了网络套接字的创建和绑定,这篇文章会通过UDP套接字实现一个UDP服务器。 先介绍将使用的接口。 recvfrom ssize_t recvfrom(int sockfd, void *buf, size_t len, int flags,struct sockaddr *src_addr,…...
主流向量数据库对比
在 AI 的 RAG(检索增强生成)研发领域,向量数据库是存储和查询向量嵌入的核心工具,用于支持高效的语义搜索和信息检索。向量嵌入是文本或其他非结构化数据的数值表示,RAG 系统通过这些嵌入从知识库中检索相关信息&#…...
54.HarmonyOS NEXT 登录模块开发教程(八):测试与调试技巧
温馨提示:本篇博客的详细代码已发布到 git : https://gitcode.com/nutpi/HarmonyosNext 可以下载运行哦! HarmonyOS NEXT 登录模块开发教程(八):测试与调试技巧 文章目录 HarmonyOS NEXT 登录模块开发教程(…...
Vue3中 ref 与 reactive区别
ref 用途: ref 通常用于创建一个响应式的基本类型数据(如 string、number、boolean 等),但它也可以用于对象或数组 返回值: ref 返回一个带有 .value 属性的对象,访问或修改数据需要通过 .value 进行 使用场景: …...
结构型——装饰器模式
装饰器模式 装饰器是指能动态地为对象添加额外的功能的一种结构型设计模式。 特点 不修改原有代码的情况下,动态地扩展一个对象的功能。支持多个装饰器叠加使用透明性,装饰后的对象与原对象保持一致,客户端无需感知装饰过程 结构模式与实…...
