M1打印进程树 (pstree)
M1: 打印进程树 (pstree)
实验指向:
https://jyywiki.cn/OS/2024/labs/M1.md
感谢jyy老师开源的OS课程,受益匪浅。
同时根据《操作系统》实验须知 与 Academic Integrity ,故不直接提供代码(水平也有限)
介绍:
1 | 计算机世界有趣的地方在于,你可以动手构建任何你认为应该可以实现的东西。我们的热身实验是一个很简单的代码练习——但我们并不是实现类似于排序、最短路径这样的算法习题,而是一个真正有意义的 “实用工具”:了解操作系统中运行的程序 (进程) 之间的层级关系,并打印进程树。如果你觉得打印进程树这个问题比较困难,我们也把问题分解一下: |
- 得到命令行的参数,根据要求设置标志变量的数值;
- 得到系统中所有进程的编号 (每个进程都会有唯一的编号) 保存到列表里;
- 对列表里的每个编号,得到它的的父亲是谁;
- 在内存中把树建好,按命令行参数要求排序;
- 把树打印到终端上。
实验要求:实现 pstree 打印进程之间的树状的父子关系
Linux 系统中可以同时运行多个程序。运行的程序称为进程。除了所有进程的根之外,每个进程都有它唯一的父进程,你的任务就是把这棵树在命令行中输出。你可以自由选择展示树的方式 (例如使用缩进表示父子关系)。
实验流程 + 所思
☕️解决问题
我们把问题分解一下:
- 得到命令行的参数,根据要求设置标志变量的数值;
- 得到系统中所有进程的编号 (每个进程都会有唯一的编号) 保存到列表里;
- 对列表里的每个编号,得到它的的父亲是谁;
- 在内存中把树建好,按命令行参数要求排序;
- 把树打印到终端上。
万物之始,开始去做
功能实现:
实现在pstree
命令中,-p
、-n
和-V
是可选参数的作用,具体情况如下:
-p
:此选项用于显示进程的PID(进程ID)。当使用-p
选项时,pstree
会在输出中显示每个进程的PID。-n
:此选项用于以数值排序的方式显示进程。通常情况下,pstree
会按照字母顺序对进程进行排序,但使用了-n
选项后,它会以数值的方式进行排序。-V
:此选项用于显示pstree
命令的版本信息。当使用了-V
选项时,pstree
会显示版本信息并退出,不会执行其他操作。
这些选项可以根据需要单独使用,也可以组合使用,例如-pn
、-np
等。每个选项都可以根据具体需求来选择是否使用,以满足用户的特定要求。
1 | int main(int argc, char *argv[]) { |
进程
进程是操作系统中的对象,因此操作系统一定提供了 API 访问它们。已经剧透过,系统里的每个进程都有唯一的编号,它在 C 语言中的类型是 pid_t
。
有关Linux使用C语言获取进程信息的内容借鉴了
https://blog.csdn.net/Once_day/article/details/136245660
前情
在计算机的世界里,Linux进程是一个非常基础而且关键的概念。它可以被理解为正在执行的一个程序的实例。每个进程都有自己独特的身份,我们称之为进程ID(PID),就像每个人都有自己的身份证号码一样。
进程有不同的状态,包括运行(正在使用CPU)、等待(等待资源可用)、停止(被挂起)和僵尸(已完成执行但等待父进程读取状态的进程)。进程的终止可以通过多种方式,如正常退出、被其他进程杀死(通过发送信号)、或系统强制终止。进程结束后,其资源会被回收,但进程的退出状态(exit status)会被保存,这对于调试和错误处理非常重要。
1 | Linux系统还支持进程的层级关系,也就是父子进程关系。当一个进程创建一个新进程时,原来的进程就是父进程,新创建的就是子进程。 |
介绍/proc目录信息
在Linux操作系统中,/proc
目录是一个非常特殊和有趣的存在,它实际上并不是存储在硬盘上的真实文件系统,而是一个虚拟文件系统,通常被称为进程信息伪文件系统(Process Information Pseudo-File System)。/proc
提供了一个窗口,通过它可以窥见内核中的世界,包括系统信息及正在运行的进程详情。
/proc
目录中的文件和子目录大都以数字命名,这些数字对应着系统中的进程ID(PID)。每一个这样的目录里面,包含了与该PID相关的信息,例如进程的内存映射(/proc/<pid>/maps)
、环境变量(/proc/<pid>/environ)
、可执行文件的链接(/proc/<pid>/exe)
等等。这些文件为系统管理员和程序员提供了一种简便的方式来监控进程和系统的内部状态。
除了进程相关信息,/proc
目录还包含了许多全系统范围的信息。例如,/proc/meminfo
文件包含了内存使用情况的详细信息,/proc/cpuinfo
提供了CPU的相关信息,/proc/net
目录包含了网络协议和配置的信息,等等。
值得一提的是,/proc
目录下的文件大多是可读的文本文件,可以直接使用常用的文本工具查看,如cat
、less
等。但也有一些文件是可写的,通过对这些文件写入特定的值,用户或程序员可以调整或配置内核参数,这是实现内核动态调优的一种方式。
一个常见的应用场景是,当系统管理员想要快速检查系统的运行状态,或者程序员在开发过程中需要获取系统或进程的某些信息时,他们就会查阅/proc
目录下的文件。例如,通过读取/proc/uptime
文件,可以获取系统已经运行了多长时间;通过查看/proc/loadavg
文件,可以了解系统的平均负载情况。
常见的子目录和文件及其功能:
路径 | 功能 |
---|---|
/proc/[pid] | 包含每个进程的信息 |
/proc/cpuinfo | 包含有关CPU的信息 |
/proc/meminfo | 包含有关内存的信息 |
/proc/net | 包含有关网络的信息 |
/proc/filesystems | 包含当前系统支持的文件系统类型列表 |
/proc/loadavg | 包含系统平均负载的信息 |
/proc/sys/kernel | 包含内核参数的目录,可用于设置和查询内核参数 |
/proc/sys/fs | 包含文件系统参数的目录,可用于设置和查询文件系统参数 |
/proc/sys/net | 包含网络参数的目录,可用于设置和查询网络参数 |
/proc/sys/vm | 包含虚拟内存参数的目录,可用于设置和查询虚拟内存参数 |
/proc/version | 包含有关内核版本的信息 |
/proc/cmdline | 包含启动时内核的命令行参数 |
/proc/self | 一个指向当前进程自身的符号链接 |
/proc/sysinfo | 包含系统信息的文件,如架构、主机名等 |
大思路
1.遍历/proc
目录下的数字开头的目录(数字即进程pid)
2.建树和打印
伪代码:
1 | 函数 readcmdops(argc, argv): |