【Linux】浅谈冯诺依曼和进程

【Linux】浅谈冯诺依曼和进程

一、冯诺依曼体系结构

在这里插入图片描述


冯诺依曼由 输入设备、输出设备、运算器、控制器、存储器 五部分组成。

冯诺依曼的设计特点

  1. 二进制表示
    所有数据(包括程序指令)均以二进制形式存储和运算,简化了硬件逻辑设计,提高了可靠性。
  2. 存储程序原理 程序与数据共同存储于同一存储器中,且程序可像数据一样被修改。
  3. 顺序执行机制 指令按线性顺序逐条执行,由程序计数器(PC)控制执行流程。
  4. ​指令结构 每条指令由操作码​(定义操作类型)和地址码​(指定操作数位置)组成。

冯诺依曼体系结构的作用

引言:外设CPU 读取速度完全不一样,如果 外设CPU 直接进行数据交互,就会导致 CPU 读取速度非常缓慢。但 冯诺依曼体系结构 就解决了这种问题,那它是怎么解决的呢?

  1. 内存作为缓冲区
    冯·诺依曼体系结构将内存作为CPU和外设之间的缓冲区。外设将数据写入内存,CPU再从内存读取数据进行处理。这种设计解决了CPU与外设之间速度不匹配的问题。例如,外设(如硬盘)的读写速度远低于CPU,通过内存作为中间存储,可以避免CPU长时间等待外设完成操作。
  2. 中断机制
    冯·诺依曼体系结构引入了中断机制,以优化CPU与外设之间的交互。外设在完成数据写入内存后,会发送中断信号通知CPU。CPU在收到中断信号后,再读取内存中的数据进行处理。这种方式避免了CPU轮询外设状态的低效操作,使得CPU可以将更多时间用于执行其他任务。
  3. 数据传输的统一性
    在冯·诺依曼体系结构中,所有数据(包括程序指令和外设数据)都通过内存进行交互。这种统一的数据流动模式简化了硬件设计,使得CPU只需要支持对内存的读写操作,而无需直接处理多种外设协议。
  4. 存储分级
    冯·诺依曼体系结构通过存储分级(如寄存器、缓存、内存、外存)来优化数据访问速度。内存作为中间层,其访问速度远高于外设,但低于CPU缓存和寄存器。通过这种分级设计,数据可以按需在不同存储层级之间流动,从而提高整体效率。
  5. 操作系统与驱动程序的支持
    操作系统通过驱动程序将外设的复杂操作抽象成统一的接口,进一步优化了CPU与外设之间的数据交互。驱动程序可以动态更新,以支持新功能,而无需修改硬件。

二、操作系统(Operator System)

概念

操作系统(Operating System,简称OS) 是管理计算机硬件与软件资源的系统软件。它提供用户接口和资源分配,是计算机系统中最基本的系统软件,任何计算机系统都包含一个基本的程序集合,统称为 操作系统(OS)
简单来讲, 操作系统 包含 :

  1. 内核(进程管理、内存管理、文件管理、驱动管理)
  2. 其他程序 (函数库、shell程序等)

设计OS的目的

  1. 对下,与硬件交互,管理所有软硬件资源

对上,为用户程序提供一个良好的运行环境

在这里插入图片描述

OS如何管理软、硬件

OS 是怎么管理软、硬件的呢?,简单6个字就可以总结:先描述,再组织

  1. 先描述 :描述起来,用 struct 结构体来描述
  2. 再组织 :通过数据结构报 struct 结构体组织起来,用链表或其他数据结构(队列、哈希等)组织起来

进程

上面讲了 OS 是怎么将软硬件资源管理起来的,那么对于进程也是再这样吗?答案是肯定的

概念

  1. 进程信息被放在一个叫做 进程控制块 的数据结构中,可以理解为描述进程属性的结构体
  2. 课本上称之为 PCBprocess 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 在内核中使用双链表进程链接起来的

在这里插入图片描述

查看进程

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

在这里插入图片描述


ps:ps axj

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

在这里插入图片描述
在这里插入图片描述

通过系统调用获取进程标识符

  • 获取进程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>intmain(){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);}}return0;}

程序运行结果:

在这里插入图片描述


可以看到父进程和子进程的 val 的值并不是一样的,我们就可以得出父子进程并不共享同一份数据的结论

进程状态

进程状态有很多种:

  • R运行状态:并不意味着进程一定在运行中,它表明进程要么在运行中,要么在运行队列中(运行队列用于管理处于“就绪状态”(Ready State)的进程。这些进程已经准备好运行,但正在等待 CPU 时间片分配。当调度器选择一个进程运行时,它会从运行队列中选取一个进程,并将其状态从“就绪”变为“运行”。
  • S睡眠状态:以为着进程在等待事件完成(也叫做可中断睡眠)
    注意: 以下有个场景可能让人误会为是 R 状态 ,但其实是 S 状态
#include<stdio.h>#include<unistd.h>#include<sys/types.h>intmain(){int cnt =0;while(1){printf("pid: %d,cnt = %d\n",getpid(),cnt++);}return0;}~

这里可能很多认为进程的状态是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的结束
  • X死亡状态:这是一个返回状态,你不会在任务列表中看到这个状态,因为这是一个瞬时状态,一下就消失了

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

在这里插入图片描述

T停止状态:可以通过发送 SIGSTOP 信号来给进程停止 (T)进程。这个被暂停的进程可以通过发送 SIGCOUT 信号让进程继续执行

在这里插入图片描述

僵死状态危害

没创建一个子进程就需要一个 PCB ,如果父进程创建了很多子进程,而没有去回收就会造成内存资源的浪费

孤儿进程

父进程如果提前退出,子进程就会变成孤儿进程,孤儿进程就会被1号 init 也就是操作系统启动后第一个运行的用户空间程序

在这里插入图片描述

进程优先级

基本概念

  • cpu资源分配的先后顺序,就是进程的优先权。
  • UID : 代表执⾏者的⾝份
  • PID : 代表这个进程的代号
  • PPID :代表这个进程是由哪个进程发展衍⽣⽽来的,亦即⽗进程的代号
  • 普通优先级:100 ~ 139
  • 实时优先级:0 ~ 99
  • PRI :代表这个进程可被执⾏的优先级,其值越⼩越早被执⾏
  • NI :代表这个进程的nice值(修正优先级数值的

优先级高的进程有优先执行权利。

在这里插入图片描述

其中 PRI(new) = PRI(采用默认值80) + nice

更改进程nice值

通过更改进程 nice 来改变进程优先级
top 命令来改变进程 nice 值:

  1. 进入top后按 “r” -> 输入进程PID -> 输入nice值

进程竞争、独立、并行、并发

  1. 竞争:本质是僧多粥少,系统进程数目众多,而CPU资源只有少量,所以进程之间具有竞争属性,为了更高效的完成任务,更合理竞争相关资源,于是就有了优先级
  2. 独立:多进程在运行时,需要独享各种资源,进程之间互不干扰,就算一个进程挂掉了,也不影响另一个进程,而如果线程挂掉了,不仅会影响其他进程,可能还会导致进程挂掉。
  3. 并行:多个进程在多个CPU下同时进行运行
  4. 并发:多个进程在同一个CPU资源下采用进程切换的方式,在同一段时间之内,让多个进程都得以推进

进程切换

在多任务操作系统中,多个进程会共享有限的 CPU 资源。为了实现高效的资源利用和良好的用户体验,操作系统需要在这些进程之间切换 CPU 的控制权。这种切换通常发生在以下几种情况:

  1. 时间片用完:在时间片轮转(Round Robin)调度算法中,当一个进程的时间片用完时,操作系统会将 CPU 切换到另一个进程。
    进程阻塞:当一个进程因为等待 I/O 操作(如磁盘读写、网络通信)而阻塞时,操作系统会将 CPU 切换到另一个就绪的进程。
    更高优先级的进程就绪:当一个更高优先级的进程进入就绪队列时,操作系统可能会抢占当前运行的进程,将 CPU 切换到优先级更高的进程。
    系统调用或中断:当进程执行系统调用或发生中断时,操作系统可能会触发进程切换。
  2. 进程切换的过程
    进程切换是一个复杂的过程,涉及到多个步骤,主要包括以下内容:
    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 的控制权交给新进程,新进程从上次被中断的地方继续执行。
  3. 进程切换的开销
    进程切换是一个相对昂贵的操作,因为它涉及到大量的上下文保存和恢复工作。每次切换都会消耗一定的 CPU 时间,具体开销包括:
    寄存器保存和恢复:保存和恢复 CPU 寄存器的值。
    内存映射切换:更新页表或段表。
    调度器开销:选择下一个进程的开销。
    缓存失效:切换进程可能导致 CPU 缓存失效,新进程需要重新加载数据到缓存中。
    因此,操作系统会尽量减少不必要的进程切换,以提高系统性能。
  4. 示例:进程切换的场景
    假设系统中有两个进程 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) ,活动队列就又有了一批新的活动进程

Read more

不止“996”!曝硅谷AI创业圈「极限工作制」:每天16小时、凌晨3点下班、周末也在写代码

不止“996”!曝硅谷AI创业圈「极限工作制」:每天16小时、凌晨3点下班、周末也在写代码

编译 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) “如果你周日去旧金山的咖啡馆,会发现几乎每个人都在工作。” 这是 AI 创业公司 Mythril 联合创始人 Sanju Lokuhitige 最近最直观的感受。去年 11 月,他特地搬到旧金山,只为了更接近 AI 创业浪潮的中心。但很快,他也被卷入了这股浪潮带来的另一面——一种越来越极端的工作文化。 Lokuhitige 坦言,他现在几乎每天工作 12 小时,每周 7 天。除了每周少数几场刻意安排的社交活动(主要是为了和创业者们建立联系),其余时间几乎都在写代码、做产品。 “有时候我整整一天都在编程,”他说,“我基本没有什么工作与生活的平衡。”而这样的生活,在如今的 AI 创业圈里并不算罕见。 旧金山 AI 创业圈的真实日常 一位在旧金山一家 AI

By Ne0inhk
黄仁勋公开发文:传统软件开发模式终结,参与AI不必非得拥有计算机博士学位

黄仁勋公开发文:传统软件开发模式终结,参与AI不必非得拥有计算机博士学位

AI 究竟是什么?在 NVIDIA CEO 黄仁勋看来,它早已不只是聊天机器人或某个大模型,而是一种正在迅速成形的“新型基础设施”。 近日,黄仁勋在英伟达官网发布了一篇长文,提出一个颇具形象的比喻——AI 就像一块“五层蛋糕”。从最底层的能源,到芯片、基础设施、模型,再到最上层的应用,人工智能正在形成一整套完整的产业技术栈,并像电力和互联网一样,逐渐成为现代社会的底层能力。 这也是黄仁勋自 2016 年以来公开发表的第七篇长文。在这篇文章中,他从计算机发展史与第一性原理出发,试图解释 AI 技术栈为何会演化成如今的形态,以及为什么全球正在掀起一场规模空前的 AI 基础设施建设。 在他看来,过去几十年的软件大多是预先编写好的程序:人类设计好算法,计算机按指令执行,数据被结构化存储在数据库中,通过精确查询调用。而 AI 的出现打破了这一模式——计算机开始能够理解图像、文本和声音,并根据上下文实时生成答案、推理结果甚至新的内容。 正因为智能不再是预先写好的代码,而是实时生成的能力,支撑它运行的整个计算体系也必须被重新设计。

By Ne0inhk
猛裁1.6万人后,网站再崩6小时、一周4次重大事故!官方“紧急复盘”:跟裁员无关,也不是AI写代码的锅

猛裁1.6万人后,网站再崩6小时、一周4次重大事故!官方“紧急复盘”:跟裁员无关,也不是AI写代码的锅

整理 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) 过去几年里,科技公司几乎都在同一件事上加速:让 AI 参与写代码。 从自动补全、自动生成函数,到直接修改系统配置,生成式 AI 已经逐渐走进真实生产环境。但最近发生在亚马逊的一连串事故,却给整个行业泼了一盆冷水——当 AI 开始真正参与生产环境开发时,事情可能远比想象复杂。 最近,多家媒体披露,本周二亚马逊内部紧急召开了一场工程“深度复盘(deep dive)”会议,专门讨论最近频繁出现的系统故障——其中,一个被反复提及的关键词是:AI 辅助代码。 一周 4 次严重事故,亚马逊内部紧急复盘 事情的起点,是最近一段时间亚马逊系统稳定性明显下降。 负责亚马逊网站技术架构的高级副总裁 Dave Treadwell 在一封内部邮件中坦言:“各位,正如大家可能已经知道的,最近网站及相关基础设施的可用性确实不太理想。” 为此,公司决定把原本每周例行举行的技术会议

By Ne0inhk
这回真的“装”到了!来OpenClaw全国纵深行,你只需要带一台电脑……

这回真的“装”到了!来OpenClaw全国纵深行,你只需要带一台电脑……

AI Agent 的风,已经从 GitHub 吹到了线下。 过去几个月,越来越多开发者开始讨论一个问题: 当 AI 不再只是聊天,而是可以执行任务,软件会变成什么样? 在这股浪潮中,一个开源项目迅速进入开发者视野——OpenClaw,在 GitHub 上获得大量关注,相关教程、实践案例不断出现。有人用它自动整理资料,有人用它管理开发流程,还有人尝试让它执行复杂的工作流。 很多开发者第一次意识到: AI 不只是工具,它可能成为“执行者”。 不过,在技术社区之外,大多数人对 Agent 的理解仍停留在概念层面。 * AI Agent 到底是什么? * 如何在自己的电脑上运行? * 普通开发者能否真正用起来? 带着这些问题,一场围绕 OpenClaw 的开发者城市行动正在展开。 ZEEKLOG 发起的OpenClaw 全国纵深行将走进 20 个城市,用最直接的方式回答一个问题——如果

By Ne0inhk