河南城建学院《操作系统》课程设计说明书设计题目:信号通信与控制专业:计算机科学与技术指导教师:班级:学号:姓名:同组人:计算机科学与工程系2011年12月30日前言操作系统是计算机应用专业学生必修的专业基础课之一。在计算机软硬件课程的设置上,它起着承上启下的作用。其特点是概念多、较抽象和涉及面广,其整体实现思想和技术又往往难于理解。操作系统对计算机系统资源实施管理,是所有其他软件与计算机硬件的唯一接口,所有用户在使用计算机时都要得到操作系统提供的服务。因此本课程的目的与任务是使学生通过本课程的学习,理解操作系统的基本概念和主要功能,掌握常用操作系统(如Linux/Windows)的一般使用和管理方法,了解它是如何组织和运作的,从而为学生以后的学习和工作打下基础。本学期通过对《操作系统原理》这门课程的学习,对操作系统相关知识有了更进一步的认识。为了检验与巩固所学习到的知识,要求设计一个信号通信与进程控制的程序,实现进程的创建,实现进程之间的互斥,软中断的捕获与重定义。完成本次课程设计,首先,必须配置操作系统编写的所需的环境,包括虚拟机的建立和相应环境建立。用VI编辑器编写相应的程序,实现进程间通信的功能。目录前言............................................................2系统环境........................................................4设计目的........................................................5程序原理........................................................5流程图..........................................................6函数说明........................................................7signal(sig,function).........................................7kill(pid,sig)................................................8fork().......................................................8lockf(files,function,size)...................................9Waiting()...................................................9wait()......................................................9exit()......................................................10调试与测试.....................................................11设计中遇到的问题及解决方法.....................................16源程序.........................................................17总结,收获与体会...............................................23参考文献.......................................................24系统环境1)文本编辑器——Windows环境平台下的EditPlus或者Linux平台下的一种文本编辑器2)汇编编译器——NASM汇编编译器3)C语言编译器——linux平台下的GCC编译器鉴于条件的限制,我们将在Windows平台下安装VMware虚拟机来搭建Linux平台。设计目的(l)进程的创建:编写一段程序,使用系统调用fork()创建两个或多个子进程。当此程序运行时,在系统中有一个父进程和其余为子进程在活动。(2)进程的控制:在程序中使用系统调用lockf()来给每一个进程加锁,实现进程之间的互斥。(3)进程通信:①软中断通信;②在程序中使用实例signal(SIGINT,SIG_IGN)和signal(SIGQUIT,SIG_IGN)进行通信操作,观察执行结果,并分析原因。(4)软中断的捕获与重定义。首先定义一个服务函数function(),然后利用signal(sig,function)系统调用来实现中断的捕获与改道。(5)使用操作系统保留给用户的信号SIGUSR1和SIGUSR2进行通信。(6)扩展程序,使之成为信号或事件驱动的应用程序。程序原理1)软中断的工作工程模拟了实际的中断处理过程,当某一软中断时间发生后,首先需要设置对应的中断标记位,触发中断事务,然后唤醒守护线程去检测中断状态寄存器,如果通过查询发现某一软中断事务发生之后,那么通过软中断向量表调用软中断服务程序。这就是软中断的过程,与硬件中断唯一不同的地方是从中断标记到中断服务程序的映射过程。在CPU的硬件中断发生之后,CPU需要将硬件中断请求通过向量表映射成具体的服务程序,这个过程是硬件自动完成的,但是软中断不是,其需要守护线程去实现这一过程,这也就是软件模拟的中断,故称之为软中断。2)在本程序中,父进程创建两个子进程,再用kill()向两个子进发出中断信号,子进程P1和P2接到信号后,用exit(0)函数正常终止自我进程(向父进程发SIGCHLD信号。父进程的wait()函数收到子进程的SIGCHLD信号后,对子进程作适当处理后(资源回收)后返回本进程。因为父进程有两个子进程,所以需要两个wait()函数来等待子进程的结束。流程图函数说明signal(sig,function)允许调用进程控制软中断信号的处理。头文件:#includesignal.h参数定义signal(sig,function)intsig;void(*function)();返回值:成功时返回旧的(以前)函数描述,失败时返回SIG_ERR。说明:信号sig的值在头文件singal.h中有完整定义和描述,可用man7signal来获得帮助。(1)sig的取值如下:信号功能值SIGHUP挂起1SIGINT键盘中断,键盘按Delete键或Break键2SIGQUIT键盘按Quit键3SIGILL非法指令4SIGTRAP跟踪中断5SIGIOTIOT指令6SIGBUS总线错7SIGFPE浮点运算溢出8SIGKILL要求终止进程9SIGUSR1用户定义信号#110SIGSEGV段违法11SIGUSR2用户定义信号#212SIGPIPE向没有读进程的管道上写13SIGALRM定时器告警,时间到14SIGTERMkill发出的软件结束信号15SIGCHLD子进程死17SIGCONT若已停止则继续18SIGPWR电源故障30kill(pid,sig)向pid为进程号的进程发送信号sig。头文件:#includesys/types.h#includesignal.h参数定义intkill(pid_tpid,intsig)pid_tpid:信号的接收进程。(pid_t可用整数代替。)若pid0,则pid为接收者的进程号,若pid=0,则接收者为同组的所有进程。若pid=-1则发送到除init进程外的所有进程。若pid-1,则接收者为-pid进程组中的每个进程。intsig:发送的信号。返回值:若成功返回0,否则为-1.当出错时,errno将被设置为合适的错误代码。fork()创建一个新进程。用法:intfork()其中返回int取值意义如下:0:创建子进程,从子进程返回的id值0:从父进程返回的子进程id值-1:创建失败lockf(files,function,size)用作锁定文件的某些段或者整个文件。头文件:#includeunistd.h参数定义:intlockf(files,function,size);intfiles,function;longsize;function的解释如下:SIG_DFL默认操作。对除SIGPWR和SIGCHLD外所有信号的默认操作是进程终结。对信号SIGQUIT、SIGRAP、SIGLL、SIGFPE、SIGBUS和SIGSEGV,它产生一内存映像文件。SIG_IGN忽视该信号的出现。Function在该进程中的一个函数地址,在核心返回用户态时,它以软中断信号的序号作为参数调用该函数,对除了信号SIGILL、SIGTRAP、SIGPWAP以外的信号,核心自动地重新设置软中断信号处理程序的值SIG_DFL,一个进程不能捕获SIGKILL信号。Waiting()等待子进程运行结束。如果子进程没有完成,父进程一直等待。Waiting()将调用进程挂起,直至其子进程因暂停或终止而发来软中断信号为止。如果在waiting()前已有子进程暂停或终止,则调用进程做适当处理后便返回。系统调用格式:staticvoidwaiting()wait()在父进程中调用第1个wait(0)后,则父进程被阻塞。进入等待第一个子进程运行结束的队列,等待子进程结束。当子进程结束后,会产生一个终止状态字,系统会向父进程发出SIGCHLD信号。当接到信号后,父进程提取子进程的终止状态字,从wait()返回继续执行原程序。同样的方式,父进程继续执行第二个wait(0),并再次阻塞,等待第2个子进程运行结束。当第二个子进程运行结束后父进程继续执行剩余的语句。exit()该函数中每个进程退出时都用了语句exit(0),这是进程的正常终止。在正常终止时,exit()函数返回进程结束状态。进程终止时,则由系统内核产生一个代表异常终止原因的终止状态,该进程的父进程都能用wait()得到其终止状态。在子进程调用exit()后,子进程的结束状态会返回给系统内核,由内核根据状态字生成终止状态,供父进程在wait()中读取数据。若子进程结束后,父进程还没有读取子进程的终止状态,则子进程就变成了“孤儿进程”,系统进程init会自动“收养”该子进程,成为该子进程的父进程,即父进程标识号变成1,当子进程结束时,init会自动调用wait()读取子进程的遗留数据,从而避免在系统中留下大量的垃圾。调试与测试(1:编写一段程序,使用系统调用fork()创建两个子进程。(2:在程序中使用系统调用lockf()来给每个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。(3:编制一段程序,使用系统调用fork()创建两个子进程,再用系统调用signal()让父进程捕捉键盘上来的中断信号(即按Del或CTRL+C键),当捕捉到中断信号后,父进程用系统调用kill()向两个子进程发出信号。在上面任务1中,增加语句signal(SIGINT,SIG_IGN)和语句signal(SIGQUIT,SIGIGN),观察执行结果,并分析原因里,signal(SIGINT,SIGIGN)和signal(SIGQUIT,SIGIGN)分别为忽略Del,或CTRL+C键信号以及忽略中断信号。设计中遇到的问题及解决方法在设计的过程中,对于各种系统的函数还是不太清楚,经过突击,把各种系统调用的函数摸清楚了,然后开始设计我们的实验,刚开始的两道题还是比较简单的,主要是进程的创建和进程之间的互斥,通过fork()和lockf()这两个函数来实现,但是进程之间的软中断通信不是太清楚,在刚开的时候,函数的调用都是不太太清楚的,但是经过我们三个人的努力,很快就将函数的使用方法搞清楚了,然后开始设计我们的题目,可是对于命令的标识符还是没有完全懂,后来我们就像老师请教,将kill