进程管理实验

一.实验目的及实验环境

实验目的:
通过观察、分析实验现象,深入理解进程及进程在调度执行和内存空间等方面的特点,掌握在POSIX 规范中fork和kill系统调用的功能和使用。
实验环境:

  1. 硬件
    (1) 主机:win7;
    (2) 内存:8G ;
    (3) 硬盘空间:500G。
  2. 软件
    Linux 操作系统,ubuntu16,安装在虚拟机下,预装有X-Window 、vi、gcc、gdb 和火狐浏览器。

二. 实验内容

通读下列代码:

/* 
* POSIX 下进程控制的实验程序残缺版 
*/ 
#include  
#include 
#include  
#include 
#include  
/* 允许建立的子进程个数最大值 */
#define MAX_CHILD_NUMBER 10 
/* 子进程睡眠时间 */
#define SLEEP_INTERVAL 2 
int proc_number=0; /* 子进程的自编号,从0开始 */
void do_something(); 
main(int argc, char* argv[])
{ 
int child_proc_number = MAX_CHILD_NUMBER; /* 子进程个数 */
int i, ch; 
pid_t child_pid; 
pid_t pid[10]={0}; /* 存放每个子进程的id */ 
if (argc > 1)
{ 
/* 命令行参数中的第一个参数表示建立几个子进程,最多10个 */ 
child_proc_number = atoi(argv[1]); 
child_proc_number
= (child_proc_number > 10) ? 10 : child_proc_number;
} 
for (i=0; i

先猜想一下这个程序的运行结果。假如运行“./process 20”,输出会是什么样?
然后按照注释里的要求把代码补充完整,运行程序。可以多运行一会儿,并在
此期间启动、关闭一些其它进程,看process 的输出结果有什么特点,记录下这个结果。
开另一个终端窗口,运行“ps aux|grep process”命令,看看process 究竟启动了多少个进程。回到程序执行窗口,按“数字键+回车”尝试杀掉一两个进程,再到另一个窗口看进程状况。
按q 退出程序再看进程情况。

三.实验问题

  1. 你最初认为运行结果会怎么样?
    从0到9顺序打印,按下数字回车后杀死相对应进程,输入q回车后,则退出程序。
  2. 实际的结果什么样?有什么特点?试对产生该现象的原因进行分析。
    实验结果与预期结不全相同,随机输出0~9号进程,循环输出。输入数字键回车后,杀死该数字所对应的进程,输入q回车后,杀死所有进程,退出程序。
  3. proc_number 这个全局变量在各个子进程里的值相同吗?为什么?
    相同,子进程的资源独立不影响。
  4. kill 命令在程序中使用了几次?每次的作用是什么?执行后的现象是什么?
    kill命令在程序中使用了2次。第一次是杀死输入的线程,输入进程号回车后,执行后接下来的结果中不会有该进程号;第二次是杀死本组所有进程。即主进程以及它创建的所有子进程。
  5. 使用kill 命令可以在进程的外部杀死进程。进程怎样能主动退出?这两种退出方式哪种更好一些?
    return或exit()函数都可以正常退出。而使用kill命令则是异常退出。
    正常退出比较好,若在子进程退出前使用kill命令杀死其父进程,则系统会托管子进程。当用kill命令使得子进程先于父进程退出时,而父进程又没有调用wait函数等待子进程结束,子进程处于僵尸状态,并且会一直保持下去,直到系统重启。子进程处于僵尸状态时,内核只保存该进程的必要信息以被父进程所需,此时子进程始终占着资源。使用return或exit()函数正常退出更好一些。

四.测试数据及运行结果

1. 正常测试数据(3组)及运行结果;
进程管理实验_第1张图片
进程管理实验_第2张图片
进程管理实验_第3张图片
2. 非正常测试数据及运行结果。
进程管理实验_第4张图片

五.总结

1. 实验过程中遇到的问题及解决办法;
遇到的问题是对进程的表示不清晰,导致if判断中的要执行的语句写错,将进程的代码理解透彻之后就发现错误了,之后就解决了。刚开始,对fork创建进程的原理不是很清楚,以至于在父子进程之间的关系不能很好的搞清楚,在知道子进程创建之后和父进程拥有一套代码,并且了解dosomething的作用之后,就对调试有了很大的帮助。
2. 对设计及调试过程的心得体会。
这次进程实验,让我清晰的看到了父进程创建子进程,手动杀死子进程,对于进程的概念也不再觉得特别抽象,也对进程的理解更加深刻,并且对系统的创建进程的方式方法更加了解,也对杀死进程的方法更加了解,也知道,而子进程和父进程是两套代码,是一样的代码,但由于dosomething函数将子进程一直运行,所以,那个while的是父进程调用的,而非子进程调用的。还有,若是已经通过输入字符杀死进程,而最后又通过q来杀死全部进程,那么有的进程就杀了两次,这一点需要优化。并且清楚,return方法或者调用exit方法是正常退出,在执行程序或者其他进程时,要注意使用正常退出的方式,减少使用异常退出。

六.附录:源代码

#include  
#include 
#include  
#include 
#include  
/* 允许建立的子进程个数最大值 */
#define MAX_CHILD_NUMBER 10 
/* 子进程睡眠时间 */
#define SLEEP_INTERVAL 2 
int proc_number=0; /* 子进程的自编号,从0开始 */
void do_something(); 
int main(int argc, char* argv[])
{ 
int child_proc_number = MAX_CHILD_NUMBER; /* 子进程个数 */
int i, ch; 
pid_t child_pid; 
pid_t pid[10]={0}; /* 存放每个子进程的id */ 
if (argc > 1)
{ 
/* 命令行参数中的第一个参数表示建立几个子进程,最多10个 */ 
child_proc_number = atoi(argv[1]); 
child_proc_number
= (child_proc_number > 10) ? 10 : child_proc_number;
} 


for (i=0; i0){
	pid[i] = child_pid;
    }
else printf("error\n");
} 

/* 让用户选择杀死哪个进程。输入数字(自编号)表示杀死该进程
* 输入q退出 */
while ((ch = getchar()) != 'q')
{ 
if (isdigit(ch)) 
{ 
/* 在这里填写代码,向pid[ch-'0']发信号SIGTERM, 
* 杀死该子进程 */ 
if(ch-'0'

你可能感兴趣的:(操作系统)