该部分的实验思路来自:read://https_rivers-shall.github.io/?url=https%3A%2F%2Frivers-shall.github.io%2F2019%2F03%2F05%2FNJU-OS-M1-pstree%2F
第一部分已经完成的工作
第一部分我们从/proc中读取了进程id和其父进程ppid,并将其信息存储在了数组中。
这一部分要为打印进程树创建相应的数据结构
要打印进程树我们需要知道每个进程的父进程,要知道每个进程的孩子进程。仅仅使用第一部分我们使用的简单数组的结构也可以实现这部分功能,但是我们可以使用一种更为高效的数据结构。
![在这里插入图片描述](https://img-blog.csdnimg.cn/41c42bf63b834e6c8a021562c675160b.png#pic_center)
相应的结构体定义
typedef struct proc{
struct proc *next;
struct proc *parent;
struct child *children;
int pid;
char pName[50];
}PROC;
typedef struct child{
const PROC* proc;
struct child *next;
}CHILD;
构建相应数据结构的思路
我们使用单链表来存储进程的信息,在加入一个进程时,由于我们知道其父进程的pid,同时可以将其父进程也加入进程链表。在后面再扫描到其父进程时,我们再完善其父进程的信息(如父进程的名字)
PROC* add_proc(const char* name,int pid,int ppid)
{
PROC *this=find_proc(pid);
/*
if(this==NULL)
{
printf("dont find process %d %s in the list\n",pid,name);
}else
{
printf(" the process %d %s in the list\n",pid,name);
}
*/
if(this!=NULL)//该进程已被加入队列
{
rename_proc(this,name);
}else
{
this=new_proc(name,pid);
if(this==NULL)
{
printf("new_proc error!\n");
}
this->next=list;
list=this;
}
if(ppid==-1)
{
// printf("没有父进程,退出!\n");
return this;//0号进程没有父进程,无需处理
}
//处理其父进程
PROC* parent=find_proc(ppid);
if(parent==NULL)
{
parent=new_proc("?",ppid);
/*
if(parent==NULL)
{
printf("add parent %d error!\n",ppid);
}else
{
printf("creat parent %d %s\n",ppid,parent->pName);
}
*/
parent->next=list;
list=parent;
}
this->parent=parent;
add_child(parent,this);
return this;
}
对于add_proc中使用到的一些函数,大家可以尝试自己实现一下。
int main()
{
char* name[8]={"(0)","(one one)","((twotwotwo))","(3333)","(4444)","(five)(five)","(sixsix)()","777777"};
add_proc(name[0],0,-1);//0号进程没有父进程
// add_proc("0",0,-1);
add_proc(name[1],1,-1);
add_proc(name[2],2,1);
add_proc(name[3],3,1);
add_proc(name[4],4,2);
add_proc(name[5],5,2);
add_proc(name[6],6,3);
add_proc(name[7],7,4);
/*
PROC *cur=list;
while(cur!=NULL)
{
printf("%d %s\n",cur->pid,cur->pName);
if(cur->parent==NULL)
{
printf("do not have parent\n");
}
cur=cur->next;
}
*/
travel(list);
return 0;
}
相应的测试结果
pid:7 name:777777 ppid:4 parentName:(4444)
i dont have children!
pid:6 name:(sixsix)() ppid:3 parentName:(3333)
i dont have children!
pid:5 name:(five)(five) ppid:2 parentName:((twotwotwo))
i dont have children!
pid:4 name:(4444) ppid:2 parentName:((twotwotwo))
my children: pid:7 pname:777777
pid:3 name:(3333) ppid:1 parentName:(one one)
my children: pid:6 pname:(sixsix)()
pid:2 name:((twotwotwo)) ppid:1 parentName:(one one)
my children: pid:5 pname:(five)(five) pid:4 pname:(4444)
pid:1 name:(one one) i dont have parent
my children: pid:3 pname:(3333) pid:2 pname:((twotwotwo))
pid:0 name:(0) i dont have parent
i dont have children!