[关闭]
@Lxjeng 2016-04-10T07:41:35.000000Z 字数 3645 阅读 913

实验三 进程基础实验


  • 姓名:梁晓静 学号:1405010530 班级:计算机5班
  • 报告提交日期:2016.4.11 报告提交截止日期:2016.4.11

一、实验题目

  • 1、在Linux环境下,用c语音编写一个程序,以树状结构(即体现父子关系)输出系统当前所有进程。
  • 2、修改do_fork函数,使用printk函数输出do_fork函数执行过程信息到日志。

二、实验目的

  • 1.理解进程和程序、进程和线程的联系与区别;
  • 2.熟悉进程的重要数据结构、进程的状态、进程的管理与控制及实现机制;
  • 3.练习获取进程执行的相关信息,理解进程的执行过程。

三、实验平台

  • 一台装有 Ubuntu 的计算机。

四、实验要求

  • 在 Linux 下,用 C 语言自己编写一个程序,要求能以树状结构(即能体 现父子关系)打印出系统当前的所有进程;
  • 重新编译内核,到源码fork.c中修改do_fork函数,调用printk函数输出程信息到日志。最后运行给定代码forktest.c,同时用另一个终端运行命令“tail-f/var/log/messages”观察输出信息。

五、实验思路和流程图

  • 本实验通过采用在用户态运行 C 程序来打印进程树。Ubuntu系统的/proc 目 录下有一组以进程号pid为目录名的文件,每个目录包含了进程的具体信息,于是通过/proc目录获得各进程的父进程ppid,获得进程树的父亲表示,再将进程树的父亲表示转换成左孩子与右孩子,最后中序遍历二叉树,输出进程信息即可。

①创建pstree.c文件;
此处输入图片的描述

查看进程树的命令 pstree
此处输入图片的描述
②用 gcc工具编译源文件;

  • $gcc –o pstree pstree.c

③运行编译好的可执行文件。

  • $./pstree

实验运行结果如图所示
此处输入图片的描述

实验过程遇到的问题:
此处输入图片的描述
此处输入图片的描述
这些都是因为写程序的时候,粗心写错了几个地方,然后又仔仔细细对照源码改的,然而运行后...
此处输入图片的描述

  • 这是乱码了么... 问了同学,说是代码错了,可是我又对照了一遍
    并没有错。所以复制粘贴了别人的就可以了...
  1. #include <unistd.h>
  2. #include <stdio.h>
  3. int main ()
  4. {
  5. pid_t fpid;
  6. int count=0;
  7. fpid=fork();
  8. if (fpid < 0)
  9. printf("error in fork!");
  10. else if (fpid == 0) {
  11. printf("i am the child process, my process id is %d/n",getpid());
  12. count++;
  13. }
  14. else {
  15. printf("i am the parent process, my process id is %d/n",getpid());
  16. count++;
  17. }
  18. printf("统计结果是: %d/n",count);
  19. return 0;
  20. }
  1. #include<stdio.h>
  2. #include <stdlib.h>
  3. #include <errno.h>
  4. #include <string.h>
  5. #include <sys/types.h>
  6. #include <stdlib.h>
  7. #include <errno.h>
  8. #include <netdb.h>
  9. #include <sys/types.h>
  10. #include <pthread.h>
  11. #include <unistd.h>
  12. #include <dirent.h>
  13. char default_path[1024]="/proc/";
  14. int s=0;
  15. typedef struct file_info
  16. {
  17. int pid; // 进程号
  18. int ppid; // 父进程号
  19. char name[1024]; // 进程名称
  20. int flag; // 进程标志
  21. int rec; // 打印进程树时用来标记是几级进程的
  22. }info;
  23. int my_getpid(char *str)//获得进程号
  24. {
  25. int len=strlen(str); char num[10]; int i,j,ret;
  26. if(strncmp(str,"Pid",3)==0)
  27. { for(i=0;i<len;i++)
  28. {
  29. if(str[i]>='0'&&str[i]<='9')
  30. break;
  31. }
  32. for(j=0;j<len-i;j++)
  33. num[j]=str[i+j];
  34. ret=atoi(num);
  35. }
  36. else ret=0;
  37. return ret;
  38. }
  39. int my_getppid(char *str) // 获得父进程号
  40. {
  41. int len=strlen(str);
  42. char num[10];
  43. int i,j,ret;
  44. if(strncmp(str,"PPid",4)==0)
  45. {
  46. for(i=0;i<len;i++)
  47. {
  48. if(str[i]>='0'&&str[i]<='9')
  49. break;
  50. }
  51. for(j=0;j<len-i;j++)
  52. num[j]=str[i+j];
  53. ret=atoi(num);
  54. }
  55. else ret=0;
  56. return ret;
  57. }
  58. int child_exist(info *file,int count,int ppid) //判断是否存在子进程
  59. {
  60. int i;
  61. for(i=0;i<count;i++)
  62. {
  63. if(file[i].flag==0&&file[i].ppid==ppid) return 1;
  64. }
  65. return 0;
  66. }
  67. void print_pstree(info *file,int count,int ppid,int rec)//打印进程树,用递归方法,中序遍历
  68. {
  69. int i,j,k;
  70. for(i=0;i<count;i++)
  71. {
  72. if(file[i].flag==0&&file[i].ppid==ppid)
  73. {
  74. file[i].rec=rec+1;
  75. file[i].flag=1;
  76. for(k=0;k<rec;k++) printf("-");
  77. printf("%s\n",file[i].name);
  78. print_pstree(file,count,file[i].pid,file[i].rec);
  79. }
  80. }
  81. }
  82. int main()
  83. {
  84. int i,j,k,total,s1,s2,count,t;
  85. char str[1024],dir[1024];
  86. struct dirent **namelist;
  87. strcpy(dir,default_path);
  88. total = scandir(dir, &namelist, 0, alphasort);
  89. printf("path=%s,total=%d\n",dir,total);
  90. for(i=0;i<total;i++)
  91. {
  92. strcpy(str,namelist[i]->d_name);
  93. if(str[0]>='0'&&str[0]<='9')
  94. count++;
  95. }
  96. printf("进程数:%d\n",count);
  97. info file[1024];
  98. i=0;t=0;
  99. while(i<total)
  100. {
  101. FILE *fp;
  102. char path[1024],name[1024];
  103. int pid,ppid;
  104. strcpy(str,namelist[i]->d_name);
  105. strcpy(path,default_path);
  106. if(str[0]>='0'&&str[0]<='9')
  107. {
  108. strcat(path,str);
  109. strcat(path,"/status");
  110. fp=fopen(path,"r");
  111. while(!feof(fp))
  112. {
  113. fgets(str,1024,fp);//pid
  114. if((s1=my_getpid(str))!=0)
  115. pid=s1;//ppid
  116. if((s2=my_getppid(str))!=0)
  117. ppid=s2;//name
  118. if(strncmp(str,"Name",4)==0)
  119. {
  120. for(j=4;j<strlen(str);j++)
  121. {
  122. if(str[j]>='a'&&str[j]<='z')
  123. break;
  124. }
  125. for(k=j;k<strlen(str);k++)
  126. name[k-j]=str[k];
  127. name[k-j-1]='\0';
  128. }
  129. file[t].pid=pid;
  130. file[t].ppid=ppid;
  131. strcpy(file[t].name,name);
  132. }
  133. fclose(fp);
  134. t++;
  135. }
  136. i++;
  137. }
  138. memset(&file->flag,0,count);
  139. memset(&file->rec,0,count);
  140. print_pstree(file,count,0,0);
  141. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注