打印Linux系统进程树并可视化

环境搭建:

  • 主机:Windows10+VirtualBox 6.1

  • 操作系统 Unbuntu 20.10 (内核版本:5.8.0-44-generic)

打印Linux系统进程树并可视化

思路:利用pstree -p 查询进程树,并将其保存在txt中,实现线程树的查看和打印;或使用ps选项;或利用/proc目录将每一个进程的子进程和父进程及其他一些信息保存在txt中(采用中序遍历的方式),将文件用java进行处理,利用前端实现可视化的界面窗口。

法一,通过pstree -p 预览进程树:

在这里插入图片描述

利用pstree -p > ~/01.txt 重定向到01.txt中。实现将进程内容储存到txt文件中,从而实现对进程地存储。

法二,ps -ef 选项

实现效果:
在这里插入图片描述

法三,中序遍历/proc目录,使用java处理数据后前端显示

遍历/proc目录代码:

    #include<stdio.h>
    #include<stdlib.h>
    #include<errno.h>
    #include<string.h>
    #include<sys/types.h>
    #include<netdb.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;
    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;
    }
    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;
    }
    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;
    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++)
    printf(" ");
    printf("%d=>%s\n",file[i].pid,file[i].name);
    print_pstree(file,count,file[i].pid,file[i].rec);
    }
    }
    }
    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);
    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);
    //pid
    if((s1=my_getpid(str))!=0)
    pid=s1;
    //ppid
    if((s2=my_getppid(str))!=0)
    ppid=s2;
    //name
    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++;
    }
    memset(&file->flag,0,count);
    memset(&file->rec,0,count);
    print_pstree(file,count,0,0);
    }

Java代码:

import javax.swing.*;
import java.io.*;
import java.io.File;

public class txtOperation {
    public static void main(String[] args) {
        File file = new File("txt/01.txt");
        int lineNumber=0;
        String[] ls= new String[10000];
        StringBuilder result = new StringBuilder();
        try{
            BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"));//构造一个BufferedReader类来读取文件
            String s = null;
            while((s = br.readLine())!=null){//使用readLine方法,一次读一行
                lineNumber++;
                ls[lineNumber]=s.toString();
                result.append( System.lineSeparator() + s);
            }
            br.close();
        }catch(Exception e) {
            e.printStackTrace();
        }
        foundp fp=new foundp(ls,lineNumber);
        fp.create();
        fp.f(1);
        System.out.print("`[");
        for(int i=1;i<=lineNumber;i++)
        {
            System.out.print("{");
            System.out.print("\"pid\":"+fp.p[i].getPid()+","+"\"pname\":\""+fp.p[i].getName()+"\",");
            System.out.print("\"son\":[");
            for (int j = 1; j <=fp.p[i].getSonNumber(); j++) {
                if(j!=fp.p[i].getSonNumber())
                System.out.print("\""+fp.p[i].getSon(j)+"\",");
                else System.out.print("\""+fp.p[i].getSon(j)+"\"");
            }
            System.out.print("]");
            if(i!=lineNumber)
            System.out.println("},");
            else System.out.println("}");
        }
        System.out.print("]`");

}
}
class  pthread{
    private String pid;
    private String name;
    private int sonNumber=0;
    private String[] son=new String[10000];

    public String getPid() {
        return pid;
    }
    public void setPid(String pid) {
        this.pid = pid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getSonNumber() {
        return sonNumber;
    }

    public void setSonNumber(int sonNumber) {
        this.sonNumber += sonNumber;
    }

    public String getSon(int j) {
        return son[j];
    }

    public void setSon(String son) {
        this.son[this.sonNumber] = son;
    }
}

class  foundp {
    String[] ls= new String[500];
    int lineNumber;
    public foundp(String[] ls,int lineNumber) {
        this.ls = ls;
        this.lineNumber=lineNumber;
    }
    pthread[] p= new pthread[10000];
    public void create()
    {
        for(int pi=0;pi<10000;pi++)
            p[pi]=new pthread();
    }
        public String f(int i){
        if(i>lineNumber)
            return null;
        int pi=0,pj;
        while(ls[i].charAt(pi)==' ')
            pi++;
        pj=pi;
        while(ls[i].charAt(pj)!='=')
            pj++;
        p[i].setPid(ls[i].substring(pi,pj));
        p[i].setName(ls[i].substring(pj+2));
        if(i==lineNumber)
        {
            return p[i].getName();
        }
        else {
            int sonp=i+1;
            while (sonp<=lineNumber)
            {
                int sonpi=0;
                while(ls[sonp].charAt(sonpi)==' ') sonpi++;
                if(sonpi==(pi+1))
                {
                    Integer ps=sonp;
                    p[i].setSonNumber(1);
                    int sonpj=sonpi;
                    while(ls[sonp].charAt(sonpj)!='=')
                        sonpj++;
                    p[i].setSon(ls[sonp].substring(sonpj+2));
                }
                else{
                    if(sonpi<=pi) break;
                }
                sonp++;
            }
            f(i+1);
        }
        return p[i].getName();
    }

}

然后利用json文件使用html+css+jss实现网页端的进程查看管理:采用grid布局,利用js获取点击事件,和innerHTML更改pid pname的操作

网页截图:
在这里插入图片描述

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
目录 I 基础知识9 1 MINIX操作系统简介11 1.1 MINIX与UNIX . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1.2 探索MINIX . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 1.3 编辑器:vi . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 1.4 编译器:CC . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.5 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 2 Intel 8086体系结构19 2.1 8086 CPU结构. . . . . . . . . . . . . . . . . . . . . . . . . . 19 2.2 运算器与指令部件. . . . . . . . . . . . . . . . . . . . . . . . 19 2.3 寄存器组. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.4 主存. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.5 堆栈. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.6 系统启动. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 2.7 二进制文件结构. . . . . . . . . . . . . . . . . . . . . . . . . . 25 3 ACK 8086汇编语言27 3.1 寻址. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 3.2 数据移动指令. . . . . . . . . . . . . . . . . . . . . . . . . . . 28 3.3 常量、标号、数据与全局变量. . . . . . . . . . . . . . . . . . 29 3.4 运算指令. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 3.5 标志位操纵指令. . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.6 串操作指令. . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 3.7 跳转、分支与循环. . . . . . . . . . . . . . . . . . . . . . . . 33 3.8 堆栈与子程序. . . . . . . . . . . . . . . . . . . . . . . . . . . 34 5 6 目录 4 实习:Hello World 37 4.1 Hello World程序. . . . . . . . . . . . . . . . . . . . . . . . . 37 4.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39 II 汇编语言进阶41 5 C与汇编联合开发43 5.1 函数调用. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 5.2 全局与局部变量. . . . . . . . . . . . . . . . . . . . . . . . . . 45 5.3 编译与连接. . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 5.4 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 6 中断与I/O 49 6.1 中断. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 6.2 输入输出设备. . . . . . . . . . . . . . . . . . . . . . . . . . . 51 6.3 编写中断处理程序. . . . . . . . . . . . . . . . . . . . . . . . 51 6.4 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53 7 实习:小游戏55 7.1 make工具. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55 7.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 III 操作系统内核59 8 进程切换61 8.1 进程模型. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61 8.2 进程的实现. . . . . . . . . . . . . . . . . . . . . . . . . . . . 62 8.3 进程切换. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64 8.4 中断嵌套. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67 8.5 MiniOS中的进程切换. . . . . . . . . . . . . . . . . . . . . . . 68 8.6 操作系统实现原则. . . . . . . . . . . . . . . . . . . . . . . . 69 9 进程通信71 9.1 信号量. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71 9.2 消息机制. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 9.3 消息机制的实现. . . . . . . . . . . . . . . . . . . . . . . . . . 76 9.4 调试消息内核. . . . . . . . . . . . . . . . . . . . . . . . . . . 78 目录7 10 实习:操作系统内核83 10.1 引导操作系统. . . . . . . . . . . . . . . . . . . . . . . . . . . 83 10.2 微内核与层次式操作系统结构. . . . . . . . . . . . . . . . . . 83 10.3 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85 IV 轻量操作系统实现87 11 设备驱动程序89 11.1 设备驱动程序原理. . . . . . . . . . . . . . . . . . . . . . . . 89 11.2 键盘设备. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91 11.3 屏幕设备. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 11.4 死锁的产生与预防. . . . . . . . . . . . . . . . . . . . . . . . 93 12 存储管理95 12.1 存储管理与系统调用服务进程. . . . . . . . . . . . . . . . . . 95 12.2 进程映像的创建与终止. . . . . . . . . . . . . . . . . . . . . . 97 12.3 替换进程映像. . . . . . . . . . . . . . . . . . . . . . . . . . . 98 13 文件系统101 13.1 文件与目录. . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 13.2 文件与目录管理. . . . . . . . . . . . . . . . . . . . . . . . . . 103 13.3 文件描述符. . . . . . . . . . . . . . . . . . . . . . . . . . . . 104 14 实习:迷你操作系统109 14.1 一个简易的Shell . . . . . . . . . . . . . . . . . . . . . . . . . . 109 14.2 实习题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110 附录111 A vi常用命令113 B 虚拟机与外部的文件交换117

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wizardAEI

喜欢就投喂一下吧O(∩_∩)O

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值