Linux进程概念

一、冯诺依曼体系结构

核心概念

冯·诺依曼体系结构,也称为普林斯顿体系结构 ,是当今几乎所有通用计算机(从智能手机到超级计算机)的设计蓝图。它由美籍匈牙利数学家约翰·冯·诺依曼及其同事在1945年发表的《First Draft of a Report on the EDVAC》报告中首次明确提出。

它的革命性思想在于将程序数据一样存储在计算机内存中,从而解决了早期计算机(如ENIAC)需要通过重新布线或设置开关来编程的难题。


核心五大组成部分

冯·诺依曼体系结构将计算机划分为五个基本部分,通过总线连接:

1. 运算器

功能: 执行所有算术运算(加、减、乘、除)和逻辑运算(与、或、非、比较)。

核心部件: 算术逻辑单元。

2. 控制器

功能: 是整个计算机的"指挥中心"。它从内存中读取指令,解码并控制其他所有部件协同工作以执行该指令。

运算器 + 控制器 合称为 中央处理器

3. 存储器

功能 : 用于存储程序(指令序列)程序需要处理的数据。其特点是可寻址、可按地址读取或写入信息。

关键特性程序和数据共存于同一存储器中,没有物理上的区分。这是冯·诺依曼结构的灵魂所在。

4. 输入设备

功能: 将外部的信息(程序和数据)输入到计算机中。例如:键盘、鼠标、触摸屏、扫描仪等。

5. 输出设备

功能: 将计算机处理的结果输出到外部世界。例如:显示器、打印机、音响等。


核心设计原则(三大要点)

1. 存储程序

这是最核心的原则。指令(程序)和数据以二进制形式不加区别地存储在同一个线性编址的内存中。这意味着计算机可以通过修改内存中的内容来改变其任务,使其变得"通用"。

2. 顺序执行

CPU通常顺序地 从内存中读取指令并执行(即一条接一条)。执行顺序由一个称为程序计数器 的寄存器决定,它存放下一条要执行的指令地址。当然,指令本身可以改变PC的值来实现跳转(如循环、判断)。

3. 五大部件组成

如上所述,计算机必须由这五个基本部件构成,并通过系统总线(数据总线、地址总线、控制总线)进行通信。


工作流程(冯·诺依曼循环)

CPU的工作是一个周而复始的循环,称为 "取指-译码-执行"循环

1. 取指 : 控制器根据程序计数器 中的地址,从内存中读取一条指令。

2. 译码: 控制器分析该指令,确定需要执行什么操作(如加法)以及操作数在哪里。

3. 执行: 控制器命令相关部件(如运算器、内存、输入/输出设备)完成该指令指定的操作。

4. 更新计数器: 程序计数器增加,指向下一条指令的地址(除非当前指令是跳转指令,会修改计数器)。

  1. 重复步骤1,开始下一个循环。

二、操作系统(Operator System)

核心定义

操作系统 是一组系统软件程序的集合,它管理计算机硬件资源,控制程序执行,并为用户和其他软件提供公共服务和便利的接口。

简单比喻:

1. 硬件是身体(CPU是大脑,内存是思维空间,硬盘是长期记忆,键盘/鼠标是感官)。

2. 操作系统是心智与人格(它协调身体各部分,决定如何思考、如何反应,提供你与外界的交互方式)。

3. 应用程序是技能(写字、画画、计算,这些技能需要心智和身体配合才能完成)。


三、进程

1.基本概念

进程=内核数据结构(task_struct)+程序的代码和数据

其中task_struct是linux内核中的一种数据结构,被装载到内存中并且包含着进程的信息

task_struct

以下保留了核心的内容:

cpp 复制代码
struct task_struct {
    /* 1. 标识信息 - 最重要 */
    volatile long state;                // 进程状态(运行/睡眠/停止等)
    int exit_state;                     // 退出状态
    pid_t pid;                          // 线程ID(调度单位)
    pid_t tgid;                         // 线程组ID(传统进程ID)
    
    /* 2. 家族关系 */
    struct task_struct __rcu *parent;   // 父进程
    struct list_head children;          // 子进程链表
    struct list_head sibling;           // 兄弟进程链表
    struct list_head tasks;             // 所有进程链表节点
    
    /* 3. 内存管理核心 */
    struct mm_struct *mm;               // 用户空间内存描述符
    struct mm_struct *active_mm;        // 活动内存描述符(内核线程用)
    
    /* 4. 调度核心 - 决定谁运行 */
    int prio;                           // 动态优先级
    int static_prio;                    // 静态优先级(nice值相关)
    unsigned int policy;                // 调度策略(CFS/实时等)
    const struct sched_class *sched_class; // 调度类
    struct sched_entity se;             // CFS调度实体(红黑树节点)
    struct list_head run_list;          // 运行队列节点
    
    /* 5. 信号处理 */
    struct signal_struct *signal;       // 指向信号结构
    struct sighand_struct *sighand;     // 信号处理函数表
    sigset_t blocked;                   // 阻塞的信号掩码
    struct sigpending pending;          // 待处理信号
    
    /* 6. 文件系统 */
    struct files_struct *files;         // 打开的文件表
    
    /* 7. 命名空间(容器化基础) */
    struct nsproxy *nsproxy;            // 命名空间代理
    
    /* 8. 时间统计 */
    u64 utime, stime;                   // 用户/内核态CPU时间
    u64 start_time;                     // 进程启动时间
    
    /* 9. 凭证(安全) */
    const struct cred __rcu *cred;      // 执行凭证(uid/gid/权限)
    
    /* 10. 栈信息 */
    void *stack;                        // 内核栈指针
    
    /* 11. 线程特定 */
    struct thread_info *thread_info;    // 底层线程信息
    
    /* 12. 通信相关 */
    struct sysv_sem sysvsem;            // System V信号量
    struct list_head ptraced;           // 被跟踪的进程列表
    
    /* 13. 杂项 */
    char comm[TASK_COMM_LEN];           // 可执行程序名
    int exit_code;                      // 退出代码
    unsigned int flags;                 // 进程标志位
};

最关键的10个字段:

cpp 复制代码
struct task_struct {
    // 1. 我是谁?
    long state;            // 状态:我当前在干什么?
    pid_t pid;             // 唯一标识符:我的ID是什么?
    pid_t tgid;            // 我属于哪个进程组?
    
    // 2. 我从哪来?
    struct task_struct *parent;  // 我的父亲是谁?
    
    // 3. 我的私人空间在哪?
    struct mm_struct *mm;  // 我的用户态内存地图
    
    // 4. 我该怎么被调度?
    int prio;              // 我的优先级
    struct sched_entity se; // 我在调度器队列中的位置
    
    // 5. 我能访问什么文件?
    struct files_struct *files;  // 我打开了哪些文件
    
    // 6. 我有什么权限?
    const struct cred *cred;      // 我的用户身份和权限
    
    // 7. 我收到了什么信号?
    struct sigpending pending;    // 别人发给我的信号
    
    // 8. 我的名字?
    char comm[16];         // 我的程序名(前16个字符)
};

内存中的嵌套世界

RAM、OS和tack_struct之间有着什么样的关系呢??由图我们可知,task_struct在OS中,task_struct管理的代码和数据在RAM中,OS又在RAM中

bash 复制代码
|-----------------------------------------------------|
|              【整个物理内存空间】                   |
|-----------------------------------------------------|
|                                                     |
|  +-----------------------------------------------+  |
|  |       【操作系统内核空间】                    |  |
|  |   (内核态,受保护,用户程序不能直接访问)       |  |
|  |                                               |  |
|  |   +---------------------------------------+  |  |
|  |   |        OS内核代码和数据                |  |  |
|  |   |  - 内核本身的指令代码                  |  |  |
|  |   |  - 全局内核数据结构                   |  |  |
|  |   |  - 设备驱动程序                      |  |  |
|  |   |                                     |  |  |
|  |   |   +-----------------------------+   |  |  |
|  |   |   |  【task_struct实例们】       |   |  |  |
|  |   |   |   (在堆或特定区域动态分配)    |   |  |  |
|  |   |   |   • task_struct A           |   |  |  |
|  |   |   |   • task_struct B           |   |  |  |
|  |   |   |   • task_struct C           |   |  |  |
|  |   |   |   ...                       |   |  |  |
|  |   |   +-----------------------------+   |  |  |
|  |   +---------------------------------------+  |  |
|  +-----------------------------------------------+  |
|                                                     |
|  +-----------------------------------------------+  |
|  |    【用户空间】(每个进程独立一份)           |  |
|  |    (用户态,进程间隔离)                      |  |
|  |                                               |  |
|  |   +--------+  +--------+  +--------+        |  |
|  |   |进程A的 |  |进程B的 |  |进程C的 |  ...   |  |
|  |   |虚拟内存|  |虚拟内存|  |虚拟内存|        |  |
|  |   +--------+  +--------+  +--------+        |  |
|  +-----------------------------------------------+  |
|                                                     |
|-----------------------------------------------------|

2.进程状态

Linux的7种进程状态

R (Running/Runnable) - 运行或可运行

进程正在CPU上执行在就绪队列中等待调度。注意:Linux将"就绪"和"运行"都归为R状态。

S (Interruptible Sleep) - 可中断睡眠

进程正在等待某个事件完成(如I/O、信号),这种睡眠可以被信号唤醒。

D (Uninterruptible Sleep) - 不可中断睡眠

进程正在等待不可被信号中断的I/O操作(通常是磁盘I/O)。这是导致进程无法被kill -9杀死的常见原因

T (Stopped) - 暂停状态

进程被信号(如SIGSTOP)暂停执行,可通过SIGCONT信号恢复运行。

t (Tracing stop) - 跟踪暂停

进程被调试器暂停(如ptrace),用于单步调试等情况。

Z (Zombie) - 僵尸状态

进程已终止,但其退出状态尚未被父进程回收(wait())。僵尸进程不占用内存但占据进程表项。

X (Dead) - 死亡状态

进程完全终止,即将被系统清理。这个状态极短暂,通常观察不到。

进程状态查看

bash 复制代码
ps axj | grep xxxx
第一部分:ps axj
bash 复制代码
ps    # process status,进程状态命令
a     # 显示所有用户的进程(包括其他用户的)
x     # 显示没有控制终端的进程(如守护进程)
j     # 显示任务格式(包含更多信息:PID、PPID、PGID、SID等)

//输出实例:
 PPID   PID  PGID   SID TTY      TPGID STAT   UID   TIME COMMAND
    0     1     1     1 ?           -1 Ss       0   0:01 /sbin/init
    1   456   456   456 ?           -1 Ssl      0   0:00 /usr/bin/docker
bash 复制代码
列位置  字段    含义
1       PPID   父进程ID
2       PID    进程ID
3       PGID   进程组ID
4       SID    会话ID
5       TTY    控制终端
6       TPGID  终端进程组ID
7       STAT   进程状态
8       UID    用户ID
9       TIME   累计CPU时间
10+     COMMAND 命令行/进程名
第二部分:|

管道符号,将ps axj的输出作为grep xxxxx的输入

第三部分:grep xxxxx
bash 复制代码
grep   # 文本搜索工具
xxxxx  # 要搜索的模式(可以是进程名、关键字等)
整体含义:

ps axj | grep xxxxx = 在所有进程信息中,查找包含"xxxxx"关键字的行

3.进程优先级

基本概念

进程优先级是操作系统调度器决定哪个进程先获得CPU时间的依据。优先级高的进程会更频繁地获得CPU时间片。

查看系统进程

bash 复制代码
ps -al

得到以下结果:

bash 复制代码
F S   UID   PID  PPID  C PRI  NI ADDR SZ WCHAN  TTY          TIME CMD
4 S     0 17207 17188  0  80   0 - 47970 do_wai pts/1    00:00:00 su
4 S  1000 17208 17207  0  80   0 - 28921 do_wai pts/1    00:00:00 bash
0 R  1000 17228 17208  0  80   0 - 38332 -      pts/1    00:00:00 ps

UID:代表执行者的身份

PID:代表进程的代号

PPID:代表这个进程由哪个进程衍生而来,为其父进程

PRI:代表进程可被执行的优先级,越小优先级越大

NI:代表这个进程的nice值 nice:[-20,+19]

更改进程优先级

top->"r"->输入进程的PID->输入nice值

PRI(最终)=PRI(默认:80)+nice

相关推荐
cooldream20093 小时前
Vim 报错 E325:swap 文件冲突的原理、处理流程与彻底避免方案
linux·编辑器·vim
i建模3 小时前
在 Rocky Linux 上安装轻量级的 XFCE 桌面
linux·运维·服务器
技术与健康4 小时前
什么是ADSE?逻辑驱动的软件工程新范式
软件工程
若风的雨4 小时前
WC (Write-Combining) 内存类型优化原理
linux
YMWM_4 小时前
不同局域网下登录ubuntu主机
linux·运维·ubuntu
zmjjdank1ng4 小时前
restart与reload的区别
linux·运维
哼?~4 小时前
进程替换与自主Shell
linux
浩浩测试一下4 小时前
DDOS 应急响应Linux防火墙 Iptable 使用方式方法
linux·网络·安全·web安全·网络安全·系统安全·ddos
niceffking5 小时前
linux 信号内核模型
linux·运维·服务器
嵌入小生0075 小时前
单向链表的常用操作方法---嵌入式入门---Linux
linux·开发语言·数据结构·算法·链表·嵌入式