欢迎来到ZyyOvO的博客✨,一个关于探索技术的角落,记录学习的点滴📖,分享实用的技巧🛠️,偶尔还有一些奇思妙想💡 本文由ZyyOvO原创✍️,感谢支持❤️!请尊重原创📩!欢迎评论区留言交流🌟 个人主页 👉 ZyyOvO 本文专栏➡️Linux驾驭之道 掌控操作系统的艺术与哲学
在计算机系统的底层架构中,操作系统肩负着资源管理与任务调度的重任。当我们启动各类应用程序时,其背后复杂的运作机制便悄然展开。程序,作为静态的指令集合,如何在系统中实现动态执行?
进程
,这一关键概念应运而生。冯诺依曼体系结构(Von Neumann Architecture)是现代计算机的理论基础,由美籍匈牙利科学家约翰·冯·诺依曼在1945年提出(基于早期科学家如埃克特、莫奇利等人的工作)。这一架构的核心思想是“存储程序”(Stored-Program),即计算机的指令和数据以二进制形式共同存储在同一个存储器中,通过逐条读取指令并按顺序执行来完成任务。
运算器(ALU)
:负责算术和逻辑运算。控制器(CU)
: 指挥其他部件协调工作(如从内存读取指令、解码并执行)。存储器(内存)
:存储程序和数据,按地址访问。输入设备(如键盘、鼠标)
:将外部信息输入计算机。输出设备(如显示器、打印机)
:将计算结果反馈给用户。负责执行所有算术运算(加减乘除)和逻辑运算(与、或、非、移位)。 通过寄存器(如累加器)临时存储运算数据。
指令周期:通过“取指-解码-执行”循环驱动计算机工作: 取指(Fetch):从内存中读取下一条指令。 解码(Decode):解析指令含义(如“将数据从地址A加载到寄存器”)。 执行(Execute):向相关部件(如ALU、内存)发送控制信号完成操作。 通过程序计数器(PC)追踪下一条指令的地址,通过指令寄存器(IR存储当前指令)
按地址访问的线性存储空间,存储程序指令和数据。
内存分级:现代计算机扩展为多级存储(寄存器→高速缓存→主存→磁盘
),缓解速度与容量矛盾。
通过总线与CPU交互,例如键盘输入数据到内存,或显示器从内存读取结果。
数据总线:传输指令和数据。 地址总线:指定内存或设备的访问位置。 控制总线:传递控制信号(如读/写、中断请求)。
关于冯诺依曼,必须强调几点:
存储器
指的是内存
一句话总结
冯·诺依曼体系结构通过“存储程序”和五大模块的协同,定义了计算机如何存储、处理信息,成为现代计算机的基石。
大家熟悉的操作系统:
操作系统(Operating System,简称 OS)是计算机系统的核心软件,扮演着“管理者”的角色,负责协调硬件资源(如CPU、内存、硬盘等)与软件应用之间的交互,并为用户和应用程序提供简单、高效的使用环境。
任何计算机系统都包含⼀个基本的程序集合,称为操作系统(OS)。笼统的理解,操作系统包括:
一句话总结
简单来说就是
内核(Kernel)
类型:
系统服务层
用户界面(Shell)
应用程序接口(API)
操作系统的定位
如何理解"管理"?
在生活中,所有的管理,无论是校长管理学生,老板管理员工,还是政府管理公民,都离不开一句话 —— 先描述,再组织!
就拿校长管理学生的例子来说,校长可以先对每个学生进行全面的描述,一个学生的姓名,学号,性别,年龄,籍贯,紧急联系人,入学年份,毕业年份,高考成绩,绩点,学分,在学校的职位,体测情况,各科成绩…
有了所有学生的描述后,将这些学生组织起来,比如分为班级,学院,宿舍等… 进行统一的管理
站在计算机的角度
操作系统对软硬件的管理,也遵循着 先描述,再组织!
,即操作系统将各种软硬件通过各自的结构体
进行描述,再将这些结构体统构成一个全局的双链表
,即操作系统对软硬件的管理就转换成了对链表的增删查改
!
一句话总结
计算机管理软硬件
struct结构体
链表
或其他高效的数据结构
系统的核心功能是管理和协调计算机硬件与软件资源,为用户和应用程序提供高效、安全且易用的环境。
资源管理:协调硬件与软件资源
处理器(CPU)管理
内存管理
设备管理
存储管理(文件系统)
用户接口:提供人机交互方式
图形界面(GUI)
命令行界面(CLI)
应用程序接口(API)
抽象与简化:隐藏硬件复杂性
硬件抽象层(HAL)
系统调用(System Call)
多任务与进程管理
进程与线程
进程同步与通信
安全与权限控制
用户身份验证
访问控制列表(ACL)
沙箱机制
错误检测与容错
异常处理
日志记录
操作系统的核心功能本质是让复杂变得简单,用户无需理解硬件细节即可高效使用计算机,同时确保资源公平、安全地服务于所有任务。
系统调用
。库函数
,就很有利于更上层用户或者开发者进行⼆次开发。库函数 | 系统调用 |
---|---|
由编程语言或第三方库提供的预定义函数(如C标准库的printf()) | 操作系统内核提供的底层接口(如Linux的read()) |
运行在用户态,无权限切换开销 | 需切换至内核态(通过软中断或特殊指令) |
示例:fopen()内部可能调用open()系统调用 | 示例:直接操作硬件资源(如内存分配、进程调度) |
交互关系
库函数调用系统调用的方式
fopen()
→ open()
printf()
→ 格式化数据 → write()
系统调用的独立性
exit()
)典型示例
场景 | 库函数 | 系统调用 |
---|---|---|
文件操作 | fread(), fwrite() | read(), write() |
内存管理 | malloc(), free() | brk(), mmap() |
网络通信 | send(), recv() | sendto(), recvfrom() |
进程控制 | system() | fork(), execve() |
关键设计差异
系统调用的限制
reboot()
)printf()
自动类型转换)总结:两者协作的意义
基础对比表(单层结构)
对比维度 | 库函数 | 系统调用 |
---|---|---|
定义 | 编程语言或第三方库提供的函数(如printf()) | 操作系统内核提供的底层接口(如read()) |
运行模式 | 始终在用户态执行 | 需从用户态切换到内核态(通过中断/特殊指令) |
性能开销 | 低(无权限切换) | 高(上下文切换消耗资源) |
可移植性 | 依赖库的跨平台能力 | 与操作系统强绑定 |
功能特性 | 封装逻辑或组合多个系统调用 | 直接操作硬件资源(内存/设备/进程等) |
特性 | 🧩 库函数 | ⚙️ 系统调用 |
---|---|---|
调用方式 | 直接函数调用 | 需通过软中断(如int 0x80) |
失败处理 | 通常返回错误码 | 设置全局errno变量 |
执行速度 | 纳秒级(无上下文切换) | 微秒级(涉及内核切换) |
版本依赖 | 随库更新可能变化 | 保持长期兼容性 |
典型示例 | strlen(), qsort() | getpid(), sched_yield() |
那在还没有学习进程之前,就问大家,操作系统是怎么管理进行进程管理的呢?很简单,先把进程描 述起来,再把进程组织起来
进程是操作系统中资源分配和调度的基本单位,是计算机程序运行的实例化体现。
进程的描述信息被放在⼀个叫做进程控制块
的数据结构中,可以理解为进程属性的集合。课本上称之为PCB(process control block)
在Linux
中描述进程的结构体叫做task_struct
,task_struct
是PCB的⼀种
task_struct
是Linux内核的⼀种数据结构,它会被装载到RAM(内存)⾥并且包含着进程的信息。内容分类:
进程标识信息
pid_t pid; // 进程ID
pid_t tgid; // 线程组ID(主线程PID)
struct task_struct *group_leader; // 线程组领导者
进程状态管理
volatile long state; // 进程状态
/* 典型状态值:
TASK_RUNNING (0) 可运行
TASK_INTERRUPTIBLE (1) 可中断睡眠
TASK_UNINTERRUPTIBLE (2) 不可中断睡眠
__TASK_STOPPED (4) 停止状态
EXIT_DEAD (16) 终止状态 */
进程调度相关
int prio; // 动态优先级
int static_prio; // 静态优先级(nice值映射)
const struct sched_class *sched_class; // 调度器类指针
struct sched_entity se; // CFS调度实体
虚拟内存管理
struct mm_struct *mm; // 内存描述符(用户空间)
struct mm_struct *active_mm; // 活跃内存描述符(内核线程使用)
文件系统
struct files_struct *files; // 打开文件表
struct fs_struct *fs; // 根目录/工作目录信息
进程信号处理
struct signal_struct *signal; // 信号处理结构体
struct sighand_struct *sighand; // 信号处理函数表
sigset_t blocked; // 被阻塞信号掩码
进程关系
struct task_struct *real_parent; // 实际父进程(fork创建者)
struct task_struct *parent; // 法定父进程(接收SIGCHLD)
struct list_head children; // 子进程链表
struct list_head sibling; // 兄弟进程链表
时间统计
u64 utime; // 用户态CPU时间(纳秒)
u64 stime; // 内核态CPU时间
struct task_cputime cputime_expires; // CPU时间限制
组织进程
可以在内核源代码里找到它。所有运行在系统里的进程都以task_struct
链表的形式存在内核里。
基本命令与工具
ps
命令(Process Status
)静态快照显示当前进程信息。
ps aux # 查看所有用户的所有进程(BSD风格)
ps -ef # 全格式显示进程(System V风格)
ps -u root # 查看指定用户(如root)的进程
ps -p 1234 # 查看特定PID(如1234)的进程
输出字段:
PID
:进程IDUSER
:进程所有者%CPU/%MEM
:CPU和内存占用率STAT
:进程状态(如 R=运行, S=睡眠, Z=僵尸)COMMAND
:启动进程的命令例如:(只截取了一部分进程)
[zwy@iZbp1dkpw5hx2lyh7vjopaZ ~]$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.2 191052 4084 ? Ss Jan14 0:34 /usr/lib/systemd/systemd --switch
root 2 0.0 0.0 0 0 ? S Jan14 0:00 [kthreadd]
root 4 0.0 0.0 0 0 ? S< Jan14 0:00 [kworker/0:0H]
root 5 0.0 0.0 0 0 ? S Jan14 0:08 [kworker/u4:0]
root 6 0.0 0.0 0 0 ? S Jan14 0:00 [ksoftirqd/0]
root 7 0.0 0.0 0 0 ? S Jan14 0:00 [migration/0]
top / htop
命令,动态实时监控进程资源占用。
例如:top命令
例如:(有些系统下可能没有预装htop
命令,需要手动下载)
Centos下:
sudo yum install -y htop
htop
命令
关键操作:
pstree
命令以树形结构显示进程父子关系。
pstree -p # 显示PID
pstree -A # 用ASCII字符简化显示
例如:
pstree -p
命令
例如:
pstree-A
命令
查看进程详细信息
进程状态文件(/proc
文件系统)
/proc/<PID>/
其中PID
是要查看的进程id
cat /proc/PID/status # 查看进程状态(内存、线程数等)
cat /proc/PID/cmdline # 查看启动命令的完整参数
例如:
查看PID为1
的进程状态,实际上 PID为1
的进程是操作系统,Linux
下叫做systemd
例如:
同样查看systemd
进程的启动命令的完整参数
[zwy@iZbp1dkpw5hx2lyh7vjopaZ process]$ cat /proc/1/cmdline
/usr/lib/systemd/systemd--switched-root--system--deserialize22
根据名称或内容过滤
例如:
ps ajx | grep process #查找过滤叫做process的进程
[zwy@iZbp1dkpw5hx2lyh7vjopaZ ~]$ ps ajx | grep process
31995 32114 32114 31995 pts/0 32114 S+ 1000 0:00 ./process
32114 32115 32114 31995 pts/0 32114 S+ 1000 0:00 ./process
32119 32147 32146 32119 pts/1 32146 S+ 1000 0:00 grep --color=auto process
结合head
命令将头一行提取出来
ps ajx | head -1 && ps ajx | grep process
[zwy@iZbp1dkpw5hx2lyh7vjopaZ ~]$ ps ajx | head -1 && ps ajx | grep process
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31995 32114 32114 31995 pts/0 32114 S+ 1000 0:00 ./process
32114 32115 32114 31995 pts/0 32114 S+ 1000 0:00 ./process
32119 32151 32150 32119 pts/1 32150 S+ 1000 0:00 grep --color=auto process
也可以根据进程的PID进行过滤查找
例如:
ps ajx | head -1 && ps ajx | grep 32114
[zwy@iZbp1dkpw5hx2lyh7vjopaZ ~]$ ps ajx | head -1 && ps ajx | grep 32114
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31994 31995 31995 31995 pts/0 32114 Ss 1000 0:00 -bash
31995 32114 32114 31995 pts/0 32114 S+ 1000 0:00 ./process
32114 32115 32114 31995 pts/0 32114 S+ 1000 0:00 ./process
32119 32155 32154 32119 pts/1 32154 S+ 1000 0:00 grep --color=auto 32114
其中过滤出来的 grep --color=auto 32114
这个进程,是因为使用grep
过滤时,其本身也是一个进程,包含了要过滤进程的信息,所以也会被找出来,如果不想让其显示,可以使用grep -v grep
反向过滤掉。
例如:
[zwy@iZbp1dkpw5hx2lyh7vjopaZ ~]$ ps ajx | head -1 && ps ajx | grep 32114 | grep -v grep
PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND
31994 31995 31995 31995 pts/0 32114 Ss 1000 0:00 -bash
31995 32114 32114 31995 pts/0 32114 S+ 1000 0:00 ./process
32114 32115 32114 31995 pts/0 32114 S+ 1000 0:00 ./process
根据资源占用排序
ps aux --sort=-%cpu | head -10 # 按CPU占用降序显示前10进程
ps aux --sort=-%mem | head -10 # 按内存占用降序显示前10进程
例如:查看CPU占用前10进程
ps aux --sort=-%cpu | head -10
例如:查看内存占用前10内存
ps aux --sort=-%mem | head -10
拓展阅读: task_struct
本文到这里就结束了,后面的文章我们会展开讲解 进程的更多话题,比如进程状态,进程优先级,进程的调度和切换,进程控制等等… 感谢您的观看!