ch1 模拟进程树

肯定有bug,因为某个90000-110000的进程号一直报错,告诉我它没有父进程???但是懒得管了

由于没有通过oj所以肯定还有什么杂七杂八的错误,但是,我今天到这儿就差不多了...好想玩原神...

总结一下:首先linux一切皆文件,进程保存在/proc中,通过man procfs可以知道有个stat显示进程号

这里我犯了第一个傻,就是之前学linux指令就意图用命令读取PPid,结果虽然能行,但是如果用c语言的话,可以尝试用scanf,就避免复杂的遍历赋值环节

得到路径的方式getPath()部分来源于我操作系统的课堂实验,说实话感觉我可能还是不太熟练,尤其是memset这个没懂,不过strcpy和strcat还是大概会用的

赞美简单的string.h

第二个傻是怎么处理命令行得到的文件和遍历得到的d_name怎么处理,我是把他们先放进一个链表里面

然后链表通过遍历递归输出最后结果

说实话感觉非常之麻烦,不过好歹是做出来了的.

可喜可贺可喜可贺

 

#include <stdio.h>
#include <assert.h>
#include <dirent.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
typedef struct Link
{
    int self;
    int father;
    struct Link *next;
}link;
static link * p;

//cat ./119/status | grep PPid | awk '{print $2}' 
//
//这段代码可以找到119的父进程,保存在gtprocs.log
int getPath(char *path,char* name){
    memset(path, 0, 1024);
    strcpy(path, "cat /proc/");
    strcat(path, name);
    strcat(path, "/status | grep PPid | awk '{print $2}' >>gtprocs.log");
    return 0;
}


void test(FILE *fp,link *p){
    if ((fp=fopen("success.log","w"))==NULL){
        printf("cant open file");
        exit(1);
    }
    link *temp=p;
    while(temp->next!=NULL){
        temp=temp->next;
        fprintf(fp, "%d %d\n",temp->self,temp->father);
    }
    fclose(fp);
}


void pstree(int n,int name){
    link *temp=p;
    for(int i=0;i<n;i++){
        printf("\t");
    }
    printf("%d\n",name);
    while(temp->next!=NULL){
        if(temp->next->father==name){
            int tempself = temp->next->self;
            temp->next=temp->next->next;
            pstree(n+1,tempself);
        }
        else{
        temp=temp->next;
        }
    }
}

int main(int argc, char *argv[]) {
    
    //打开目录

    DIR *proc ;
    if((proc= opendir("/proc"))==NULL) //打开目录,将打开的目录信息放至 dirp 中,若为空,则打开失败
    { 
        printf("Open Directory %s Error:%s\n",argv[1]); 
        exit(1); 
    } 
    

    //读取目录
    p=(link*)malloc(sizeof(link));
    link * temp=p;
    struct dirent *direntp;
    while((direntp = readdir(proc)) != NULL) 
    {
        //全数字,需要的进程
        if(strspn(direntp->d_name, "0123456789")==strlen(direntp->d_name)){
            
            char path[1024];
            if(getPath(path,direntp->d_name)!=0){
                printf("getPath error!");
                exit(1);
            }


            //把信息存入文件gtprocs.log

            system(path);
            

            //把信息存入链表中

            link * a=(link*)malloc(sizeof(link));
            a->self=atoi(direntp->d_name);
            //father之后再处理
            temp->next=a;
            temp=a;
        }
    }
    
    
    //向链表写入父进程的名字
    FILE *fp;
    if ((fp=fopen("gtprocs.log","r"))==NULL){
        printf("cant open file");
        exit(1);
    }
    temp=p;
    while(temp->next!=NULL){
        temp=temp->next;
        fscanf(fp, "%d\n",&temp->father);
    }
    fclose(fp);
    test(fp,p);
    pstree(0,0);
    return 0;
}

  成果:

 

 关于明天的计划,实现携程还是实现qemu的贪吃蛇,感觉还是先实现一个游戏试试比较好.(其实是我比较怕,这个jyy都说困难的协程了

posted @ 2021-12-14 20:49  夏吾  阅读(36)  评论(0)    收藏  举报