shlab日志2.11&报告2.3
实验日期:2020.6.1-2020.6.5
一、比较trace09~10执行不同结果,编程实现内建命令bg和fg的do_bgfg处理函数
1、 比较trace09~10的执行结果
两个文件分别用于测试内建bg和fg指令;
执行trace09结果如下:
执行到bg % 2时,tsh直接跳过(因为尚未编写do_bgfg处理函数),最终job[2]依然是停止状态;而ref-tsh则执行了内置bg命令,将该任务从停止变为执行状态;
执行fg %1会将后台的作业1停止之后添加到前台运行,tsh无法处理fg命令因此[1]一直在后台运行,而ref-tsh则将[1]通过第一个fg从后台执行到停止,接着第二个fg将其加入前台运行,因此jobs后列表中没有[1];
2、 编程实现内建命令bg和fg的do_bgfg()处理函数
思路:
处理bg和fg命令的函数,主要是解析参数,判断是否会出现命令错误。找到需要操作的进程(注意‘%’号,有则表示为通过jid以及getjobjid函数找到job后得到pid,无则表示通过pid以及getjobpid函数得到job判断job是否存在),然后用kill函数对它发出SIGCONT信号,因为前面创建进程的时候都是用setgpid,每个进程在单独 一个进程组,所以直接用kill即可,进程继续执行之后,只需要给进程改一下state;前台进程的话,除了要改state,还要waitfg直到它执行完成。
代码实现:
二、验证trace09~10
trace09中bg %2命令被正确执行后会将作业2放到转为后台运行,jobs后[2]显示running;trace10中执行fg %1会将后台的作业1停止之后添加到前台运行直到终止,故jobs后列表为空,可以看出执行结果已经与ref-tsh一致;
至此,我们需要填充的函数全部完成,接下来进行整个的shell的验证。
三、验证trace11~15并解释与记录
1、 trace11
ps a 显示现行终端机下的所有程序;
通过SIGINT信号将Job[1](26001)进程终止,ps a指令查看发现无26001;
2、 trace12
trace12文件中主要是验证TSTP命令;
./mysplit 4创建并将子进程挂起 4 秒,而父进程在2秒后发送SIGTSTP信号使子进程停止直到下一个SINCONT,因此看到子进程为停止状态,ps a指令查看发现(26019)进程存在;
3、 trace13
trace13文件主要是INT停止进程后再用 fg启动;
父进程发送 SIGTSTP 信号使子进程停止,因此执行 jobs 指令,可以看到子进程处于 Stopped状态,用ps a指令查看进程26033依然存在。然后执行 fg %1 指令,将后台停止的作业切换至前台运行直到终止,再次 ps a 指令查看(上右图)发现26033已经不存在了;
4、 trace14
trace14文件验证fg、bg命令的正确性,这里只有fg %1、TSTP、bg %1和jobs是可执行的(因为只有这一个进程),先将进程转化为前台运行,再发生SIGTSTP停止它,最后用bg命令重启它,jobs执行后列表中的该进程为正在后台运行。
5、 trace15
没有实现命令 bogus,所以执行./bogus 命令会报错;
首先创建子进程挂起10s,2s后被INT终止;接下来创建两个子进程然后执行jobs观察到两个进程运行中,将进程1放入前台后TSTP停止它,再jobs发现该进程已停止;后面执行 bg %3 命令报错(没有3);然后将进程1放入后台运行后jobs,该进程正在进行;最后将其放入前台运行直到结束后退出。
四、实验总结
shell lab总体来说难度较大(个人认为),因为开头没有理解shell的流程,对很多命令的运行情况不熟悉,所以对出来的结果很不解。不过后来慢慢理清了运行顺序和情况、信号的作用、进程的运行情况和周期以及运行过程,就知道应该注意的点在哪里了,然后一步步的实现就可以了,这个实验让我对shell和进程的理解加深了很多。