news 2026/2/23 21:51:10

操作系统课程设计:3-打印进程树

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
操作系统课程设计:3-打印进程树

1.实验目的

1.了解proc文件系统

2.理解task_struct结构及内核进程控制块链表遍历机制

3.采用添加内核模块技术和访问/proc目录方法,打印进程树

2.实验截图及结果分析

(1)实验截图

①访问/proc目录方法打印进程树

②添加内核模块技术打印进程树

(2)实验结果分析

从实验截图结果来看,通过访问/proc目录和添加内核模块这两种方式,均成功打印出了proc文件中包含的进程信息,且在进程树层级结构的呈现效果上各有特点。

用户态编程(访问/proc目录方法)通过编写的pstree.c代码,实现了从/proc下各进程status文件中读取、解析关键信息,my_getpid和my_getppid函数成功提取出进程的PID和PPID,特定的字符串处理逻辑解析出进程名,在print_pstree函数里,借助统计子进程数量和记录已打印子进程数,依据递归深度精准控制缩进和连接符的打印,最终呈现的进程树清晰展示了进程名、进程id和父进程id,层级结构一目了然,父子进程关系清晰可辨,极大方便了对进程间关系的理解和分析。

内核态编程(添加内核模块技术)中,pstree2.c的print_tree2函数借助list_for_each遍历cur->children链表,运用深度优先算法递归打印子进程,从实验截图的打印结果来看,不仅呈现了进程名,还包含了PID号,并且通过缩进和特定符号形成了树形结构,清晰体现了进程间的层级关系,让进程树的展示更加直观,既保留了内核态遍历的高效性,又通过补充PID和优化结构增强了信息的完整性和可读性。

3.实验程序

(1)访问/proc目录方法打印进程树

pstree.c

#include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <netdb.h> #include <sys/types.h> #include <pthread.h> #include <unistd.h> #include <dirent.h> char default_path[1024] = "/proc/"; int s = 0; typedef struct file_info { int pid; int ppid; char name[1024]; int flag; int rec; } info; // 从字符串中提取 PID int my_getpid(char *str) { int len = strlen(str); char num[10]; int i, j, ret; if (strncmp(str, "Pid", 3) == 0) { for (i = 0; i < len; i++) { if (str[i] >= '0' && str[i] <= '9') break; } for (j = 0; j < len - i; j++) { num[j] = str[i + j]; } ret = atoi(num); } else ret = 0; return ret; } // 从字符串中提取 PPID int my_getppid(char *str) { int len = strlen(str); char num[10]; int i, j, ret; if (strncmp(str, "PPid", 4) == 0) { for (i = 0; i < len; i++) { if (str[i] >= '0' && str[i] <= '9') break; } for (j = 0; j < len - i; j++) { num[j] = str[i + j]; } ret = atoi(num); } else ret = 0; return ret; } // 检查是否存在指定父进程 ID 的子进程 int child_exist(info *file, int count, int ppid) { int i; for (i = 0; i < count; i++) { if (file[i].flag == 0 && file[i].ppid == ppid) return 1; } return 0; } // 递归打印进程树 void print_pstree(info *file, int count, int ppid, int rec) { int i, j, k; int child_count = 0; // 记录当前父进程下子进程数量 int printed_child = 0; // 记录已打印子进程数量 // 统计子进程数量 for (i = 0; i < count; i++) { if (file[i].flag == 0 && file[i].ppid == ppid) { child_count++; } } for (i = 0; i < count; i++) { if (file[i].flag == 0 && file[i].ppid == ppid) { file[i].rec = rec + 1; file[i].flag = 1; // 打印缩进和连接符 for (k = 0; k < rec; k++) { if (k < rec - 1) { printf("│ "); } else { if (printed_child == child_count - 1) { printf(" "); } else { printf("├── "); } } } printf("[%d]%s\n", file[i].pid, file[i].name); print_pstree(file, count, file[i].pid, file[i].rec); printed_child++; } } } int main() { int i, j, k, total, s1, s2, count, t; char str[1024], dir[1024]; struct dirent **namelist; strcpy(dir, default_path); total = scandir(dir, &namelist, 0, alphasort); printf("path=%s,total=%d\n", dir, total); count = 0; for (i = 0; i < total; i++) { strcpy(str, namelist[i]->d_name); if (str[0] >= '0' && str[0] <= '9') count++; } printf("进程数:%d\n", count); info file[1024]; i = 0; t = 0; while (i < total) { FILE *fp; char path[1024], name[1024]; int pid, ppid; strcpy(str, namelist[i]->d_name); strcpy(path, default_path); if (str[0] >= '0' && str[0] <= '9') { strcat(path, str); strcat(path, "/status"); fp = fopen(path, "r"); while (!feof(fp)) { fgets(str, 1024, fp); if ((s1 = my_getpid(str)) != 0) pid = s1; if ((s2 = my_getppid(str)) != 0) ppid = s2; if (strncmp(str, "Name", 4) == 0) { for (j = 4; j < strlen(str); j++) { if (str[j] >= 'a' && str[j] <= 'z') break; } for (k = j; k < strlen(str); k++) { name[k - j] = str[k]; } name[k - j - 1] = '\0'; } file[t].pid = pid; file[t].ppid = ppid; strcpy(file[t].name, name); } fclose(fp); t++; } i++; } // 初始化标志位和递归深度 for (i = 0; i < count; i++) { file[i].flag = 0; file[i].rec = 0; } print_pstree(file, count, 0, 0); return 0; }

(2)添加内核模块技术打印进程树

pstree2.c

#include<linux/module.h> #include<linux/sched.h> #include<linux/list.h> typedef struct task_struct ts; // 递归打印进程树 void print_tree2(ts *cur,int blanks){ int i; for(i=1;i<=blanks;i++) printk(" "); printk("%s\n",cur->comm); struct list_head *list; list_for_each(list,&cur->children){ ts *p=list_entry(list,struct task_struct,sibling); print_tree2(p,blanks+4); } } // 模块初始化函数 int init_pstree2(void){ ts *cur; // 找到 init 进程(PID 为 1) for(cur = current; cur->pid != 1; cur = cur->parent); print_tree2(cur,0); return 0; } // 模块退出函数 void exit_pstree2(void){ } // 注册模块初始化函数 module_init(init_pstree2); // 注册模块退出函数 module_exit(exit_pstree2);

② Makefile

obj-m := pstree2.o KERNELDIR ?= /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules clean: rm -rf *.o .*.cmd *.ko *.mod.c
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/19 0:21:18

24、应用上架与管理全攻略

应用上架与管理全攻略 在当今数字化的时代,应用程序的开发和销售成为了许多开发者追求的目标。将应用成功上架到应用商店并进行有效的管理,是实现这一目标的关键步骤。下面将为大家详细介绍应用上架到 Windows 应用商店的全过程,以及上架后的监控和更新方法。 1. 年龄评级…

作者头像 李华
网站建设 2026/2/23 6:41:00

3分钟掌握CodiMD代码高亮:从基础配置到主题定制的完整指南

3分钟掌握CodiMD代码高亮&#xff1a;从基础配置到主题定制的完整指南 【免费下载链接】codimd CodiMD - Realtime collaborative markdown notes on all platforms. 项目地址: https://gitcode.com/gh_mirrors/co/codimd 作为一名开发者或技术写作者&#xff0c;你是否…

作者头像 李华
网站建设 2026/2/18 8:18:58

SuperTiled2Unity实战:从Tiled地图到Unity场景的无缝集成方案

SuperTiled2Unity实战&#xff1a;从Tiled地图到Unity场景的无缝集成方案 【免费下载链接】SuperTiled2Unity Imports Tiled files to Unity. Better than regular Tiled2Unity. 项目地址: https://gitcode.com/gh_mirrors/su/SuperTiled2Unity 作为一名长期使用Tiled进…

作者头像 李华
网站建设 2026/2/23 13:06:08

UI-TARS桌面版终极指南:零基础快速掌握AI智能助手

UI-TARS桌面版终极指南&#xff1a;零基础快速掌握AI智能助手 【免费下载链接】UI-TARS-desktop A GUI Agent application based on UI-TARS(Vision-Lanuage Model) that allows you to control your computer using natural language. 项目地址: https://gitcode.com/GitHub…

作者头像 李华
网站建设 2026/2/19 3:01:23

终极AI篮球分析系统:用智能算法重塑投篮训练新标准

终极AI篮球分析系统&#xff1a;用智能算法重塑投篮训练新标准 【免费下载链接】AI-basketball-analysis 项目地址: https://gitcode.com/gh_mirrors/ai/AI-basketball-analysis 还在为投篮命中率不稳定而烦恼&#xff1f;想用科技手段精准提升篮球技术&#xff1f;这套…

作者头像 李华
网站建设 2026/2/22 19:48:52

Android移动虚拟化新纪元:Vectras VM深度解析与应用指南

Android移动虚拟化新纪元&#xff1a;Vectras VM深度解析与应用指南 【免费下载链接】Vectras-VM-Android Its a Virtual Machine App for Android Which is Based on QEMU 项目地址: https://gitcode.com/gh_mirrors/ve/Vectras-VM-Android 还在为无法在移动设备上运行…

作者头像 李华