实验五 UNIX 信号处理.doc_第1页
实验五 UNIX 信号处理.doc_第2页
实验五 UNIX 信号处理.doc_第3页
实验五 UNIX 信号处理.doc_第4页
实验五 UNIX 信号处理.doc_第5页
已阅读5页,还剩2页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

实验五 信号处理一、实验要求本实验要求利用可靠信号机制解决信号处理时可能出现的时间窗口,以及非局部转移等问题,将学习使用sigaction,alarm,sigpending,sigsetjmp和siglongjmp等函数解决在处理信号时遇到的问题。二、实验思路1. 一个方便的开始:在程序清单1-8的基础上进行修改。可以直接利用系统shell(在cs8是bash):execl(“/bin/sh”, “sh”, “-c”, buf, (char *) 0);这样程序sigtest就具有系统shell的全部功能。如果命令带“-t”选项,则在创建执行上面函数的子进程之前,必须设置闹钟;在子进程结束之后,必须将闹钟清零。2. 需要处理的信号:因为需要使用闹钟,所以实验需要处理两个信号:SIGALRM和SIGQUIT。如果当前程序正在执行用户命令,则信号处理函数必须“杀死”用户命令进程:kill(pid, SIGKILL);/ pid为用户命令进程的ID对于信号SIGQUIT还有一种可能:正在接收用户输入的命令串。此时需要放弃当前输入,重新开始接收输入。解决方法可能需要使用非局部转移机制。3. 信号SIGALRM和SIGQUIT之间嵌套关系的处理如果这两个信号同时发生,或者在处理信号SIGALRM时产生信号SIGQUIT(或者反过来),那么应当如何处理?无论如何,如果同时存在多个未决信号,系统总是一个信号处理完了,再处理下一个信号,但是在处理完全部未决信号之前,不会返回被中断的函数或系统调用。因此合理的处理方法是,无论上述两个信号哪个先处理,另一个未决信号就应该忽略(清除未决信号);在处理其中一个信号时,屏蔽另一个信号(如果发生,就是未决信号)。static volatile pid_t pid;/ 全局变量,存放执行用户命令的子进程的ID,/ 非0表正在执行用户命令设置信号SIGALRM处理方式的代码(供参考):struct sigactionact, oact;Act.sa_handler = func;/ 信号SIGALRM的处理函数sigemptyset(&act.sa_mask);act.sa_mask |= SIGQUIT;/ 在处理信号SIGALRM时,屏蔽信号SIGQUITact.sa_flags = 0;#ifdef SA_RESTAT/ 如果定义了该常量,则系统默认不重启,应改为重启act.sa_flags |= SA_RESTART;#endifsigaction(SIGALRM, &act, &oact);信号SIGQUIT处理函数的末尾应该包含如下代码段(供参考):sigset_tpendmask;sigemptyset(&pendmask);sigpending(&pendmask);/ 获得未决信号集合pid = 0;/ 表示当前无正在执行的用户命令alarm(0);/ 清除闹钟if(sigsmember(&pendmask, SIGALRM) / 存在未决信号SIGALRMsignal(SIGALRM, SIG_IGN);/ 清除未决信号SIGALRMsigaction(SIGALRM, &act, NULL);/ 恢复原来的处理方法三、程序代码#include apue.h#includestatic void sig_int(int);static void sig_alrm(int);static volatile pid_t pid;/ 全局变量,存放执行用户命令的子进程的ID, 非0表正在执行用户命令static sigjmp_buf jmpbuf;Sigfunc* signal(int signo,Sigfunc*func);int main(int argc,char*argv) char bufMAXLINE; int status; int time=0; if(argc=3) if(strcmp(argv1,-t)=0) time=atoi(argv2); else err_sys(input error!); printf(%); if(time) alarm(time); if(signal(SIGQUIT,sig_int)=SIG_ERR) err_sys(signal error!); if(signal(SIGALRM,sig_alrm)=SIG_ERR) err_sys(signal error!); sigsetjmp(jmpbuf,1); printf(%); if(time) alarm(time); while(fgets(buf,MAXLINE,stdin)!=NULL) if(bufstrlen(buf)-1=n) bufstrlen(buf)-1=0; if(pid=fork()0) err_sys(fork error!); else if(pid=0) execl(/bin/sh,sh,-c,buf,(char*)0); err_ret(couldnt execute: %s,buf); exit(127); waitpid(pid,&status) pid=0; alarm(0); printf(%); exit(0); Sigfunc* signal(int signo,Sigfunc*func) /设置信号SIGALRM处理方式 struct sigaction act,oact; act.sa_handler=func; / 信号SIGALRM的处理函数 sigemptyset(&act.sa_mask); act.sa_flags=0; if(signo=SIGALRM) sigaddset(&act.sa_mask,SIGQUIT); /这句话是经高人指点才写出来的 #ifdef SA_RESTART act.sa_flags|=SA_RESTART; #endif if (sigaction(SIGALRM,&act,&oact)0) kill(pid,SIGKILL); else printf(n); siglongjmp(jmpbuf,1); if(sigemptyset(&pendmask)0) err_sys(sigemptyset error!); if(sigpending(&pendmask)0) kill(pid,SIGKILL); if(sigemptyset(&pendmask)0) err_sys(sigemptyset error!); if(sigpending(&pendmask)0) err_sys(sigpending error!); if(sigismember(&pendmask,SIGQUIT) signal(SIGQUIT,SIG_IGN); signal(SIGQUIT,sig_int); siglongjmp(jmpbuf,1);四、实验结果源程序名:myshell.c可执行程序名:myshell编译方法:gcc myshell.c error2e.c o myshell 结束方法:ctrl+c运行过程:设了时间限制以后,会在限制时间到达后输出Time Out!,一旦在时间内输入命令,就会推出时间限制。按下ctrl+c后退出五、心得体会本次实验感觉难度比较大, 实验要求对信号的处理有比较深入的了解。题目中给出了实验思路,但由于对信号

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论