文章定位:写一下这个lab有的坑,防止下次继续踩坑。若想自己解坑,read every word carefully in wrtie-up。
问题1: 前台运行的程序,要不要加入工作队列(一个放job的数组)?
前台进程是要等待完成的,除非其被信号中断,否则,就没有放入数组的必要。但是,在处理之前不知道其会不会被结束(ctrl+c)或停止(ctrl+z),所以,要加入。若进程没被中断,就在其运行结束后,从数组中删除;若被中断,则在信号处理函数中改变其状态(状态记录在job结构体中)。
eval函数是整个作业的主流程所在,大多代码在课件中已经给出,但等待前台进程(waitfg)要自己写。后台任务只要加入数组,然后,在sigchild handler中处理就好了。前台进程要等待其结束。
坑1(waitfg):为什么前台进程没有响应信号?
在waitfg函数中的waitpid要用WUNTRACED选项。使用该选项的waitpid在子进程被信号中断时,也返回。否则,waitpid就一直一直等待进程结束,而进程已经被信号中断了,不会返回了。同时,在waitpid返回后检测status,确认进程的返回状态,再决定是否从数组中删除进程。
坑2(waitfg):为什么进程能收到外部信号,却不能处理自己发的信号 trace16?
trace16中,程序自己给自己发了终止和停止信号。这个信号不能被信号处理函数捕获。这时候只能通过判断waitpid的返回状态判断进程的状况,然后,采取相应的措施。参考链接:http://man7.org/linux/man-pages/man2/kill.2.html
坑3(sigchld_handler):为什么明明给了一个后台命令,程序却在等命令结束?
问题还是waitpid,要使用 WUNTRACED | WNOHANG 选项,子进程被终止时返回,也不要等待没有退出的子进程。我用的是while循环,防止有子进程没有被回收。如果不用选项,它就一直一直等。
sigint_handler和sigtstp_handler坑不大,只要前台进程有放进数组,现在就能找到哪个进程该被终止或停止,在删除任务的时候要屏蔽信号,在终止进程的时候要改变子进程的状态。
坑4(do_bgfg):这个边界条件测试的也太细了吧!!
某个trace里面比较细致的测了这个函数的边界条件,在执行程序的时候要维护子进程的状态,如果对停止的子进程操作,首先发送SIGCONT信号。
感觉也没有很多坑,可是却调了两天,才通过所有的trace,哎~~┭┮﹏┭┮