LINUX信号ppt课件_第1页
LINUX信号ppt课件_第2页
LINUX信号ppt课件_第3页
LINUX信号ppt课件_第4页
LINUX信号ppt课件_第5页
已阅读5页,还剩76页未读 继续免费阅读

下载本文档

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

文档简介

1、第四章第四章 LINUX信号信号主要内容:主要内容: 信号相关概念信号相关概念 信号的运用信号的运用 信号的处置信号的处置信号信号signal是向进程发送是向进程发送的软件通知,通知进程有事件的软件通知,通知进程有事件发生发生进程可以从三个方面运用信号 指定当收到信号时进程的指定当收到信号时进程的处置函数处置函数 阻塞一个信号阻塞一个信号 向另外一个进程发送信号向另外一个进程发送信号引发信号的事件发生时,信号就被生成generate了进程根据信号采取行动时,信号就被传送deliver了信号的寿命lifetime就是信号的生成和传送之间的时间间隔曾经生成但还未被传送的信号被称为挂起pending

2、的信号假设在传送信号时进程执行了信号处置程序signal handler,那么进程就捕捉catch到了这个信号LINUX中信号种类的数目和详细的平台有关:内核用一个字代表一切的信号因此字的位数就是信号种类的最多数目常见信号及用途常见信号及用途值值宏名宏名用途用途12389101214151719SIGHUPSIGINTSIGQUITSIGFPESIGKILLSIGUSR1SIGUSR2SIGALRMSIGTERMSIGCHLDSIGSTOP从终端上发出的结束信号来自键盘的中断信号来自键盘的退出信号浮点异常信号结束接收信号的进程用户自定义用户自定义进程的定时器到期时发送此信号Kill命令发出的信

3、号标识子进程停止或结束的信号来自键盘或调试程序的停止执行信号如何发送信号?如何发送信号?用法表用法表#include int kill(pid_t pid,int sig); kill调用胜利:前往调用胜利:前往0调用失败:前往调用失败:前往-1并设置并设置errno pid0,kill就向pid进程发送信号 pid=0,kill就向调用进程的进程组成员发送信号 pid=-1,kill就向一切它有权发送信息的进程发送信号 pid-1,kill将信号发送到组id等于|pid|的进程组中去例例1:if(kill(3423,SIGUSR1)=-1) perror(“Failed t send the

4、 SIGUSR1 signal);例例2:if(kill(getppid(),SIGTERM)=-1) perror(“Failed to kill parent);进程调用kill需求知道进程的id号,所以kill常用于两个联络非常严密的进程之间用法表用法表#include int raise(int sig); raise调用胜利:前往调用胜利:前往0调用失败:前往非零的错误值调用失败:前往非零的错误值并设置并设置errno例例1:if(raise(SIGUSR1)!=0) perror(“Failed to raise SIGUSR1);用法表用法表#include unsigned i

5、nt alarm(unsigned int secs); alarm前往0或以前设置的余留秒数例例1:#include int main(void) alarm(10); for(;);用法表用法表#include int pause(void); pause总是前往-1,假设被信号中断,设置errnopause会把调用它的进程挂起来,使该进程不再耗费CPU时间,直至该进程接纳到一个信号才会恢复执行v 信号的捕获与处置进程在收到信号后,有三种处置方法 接受默许动作接受默许动作 彻底忽略信号的发生彻底忽略信号的发生 接受用户自定义的默许动作接受用户自定义的默许动作在进程的义务构造体中,有两个成员

6、项用于处置接纳的信号unsigned long signal;unsigned long blocked; signal用于存放接纳到且尚未处置的信号 blocked用于存放被阻塞的信号,但SIGKILL和SIGSTOP不能被阻塞每种信号都有其对应的处置函数,进程对一切信号处置函数集中由构造体signal_struct来管理struct signal_struct int count; struct sigaction action32;count:共享信号处置函数的计数值action:该进程的信号处置函数表struct sigaction void (*sa_handler)(int); s

7、igset_t sa_mask; int sa_flags; void (*sa_sigaction)(int,siginfo_t *, void *);sa_handler指定接纳到信号后的处置函数,有三种取值:SIG_DFL:系统默许处置函数SIG_IGN:忽略信号函数地址:只需整形参数sa_mask:在执行信号处置函数时,系统会阻塞sa_mask所指定的信号集sa_flags:用来改动信号的行为属性sa_flags的取值:的取值:SA_RESETHAND:使得在执行完该信号处置函数之后重新设为SIG_DFLSA_SIGINFO:需求传送附加信息给信号处置函数,此时运用sa_sigacti

8、on成员task_structsignalsigblockedsignal_structcountaction0action1sigactionsa_handlersa_masksa_flagssa_sigaction信号信号处置处置函数函数代码代码v 信号掩码和信号集的操作#include int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset(sigset_t *set,int signo);int sigdelset(sigset_t *set,int signo);int sigismembe

9、r(const sigset_t *set,int signo);int sigprocmask(int how,const sigset_t *set, sigset_t *oset);进程可以用sigprocmask来检查或修正它的进程信号掩码 how:阐明信号掩码的修正方式 set:修正中用到的信号集 oset:保管修正前的信号集参数参数how的常用取值的常用取值SIG_BLOCK:向当前被阻塞的信号中添加一个信号集SIG_UNBLOCK:从当前被阻塞的信号中删除一个信号集SIG_SETMASK:将指定的信号集设置为被阻塞的信号例例1:#include main() sigset_t s

10、et1,set2; sigfillset(&set1); sigfillset(&set2); sigdelset(&set2,SIGINT);sigdelset(&set2,SIGQUIT);sigprocmask(SIG_SETMASK,&set1,NULL);sigprocmask(SIG_UNBLOCK,&set2,NULL);sigprocmask(SIG_UNBLOCK,&set1,NULL);例例2:#include #include #include #include #include #include int main(void) pid_t child; sigset_t

11、mask,omask; if(sigfillset(&mask)=-1)| (sigprocmask (SIG_SETMASK,&mask,&omask)=-1) perror(“Failed to block the signals); return 1; if(child=fork()=-1) perror(“Failed to fork child); return 1;if(child=0) execl(“/bin/ls,ls,-l,NULL); perror(“Child failed to exec); return 1;if(sigprocmask(SIG_SETMASK,&om

12、ask,NULL)=-1) perror(“Parent failed to restore signal mask); return 1;if(wait(NULL)=-1) perror(“Parent failed to wait for child); return 1;return 0在拥有大量文件的任务目录中运转上面的程序,在执行的各个不同阶段输入Ctrl+c,判别发生的情况v 捕捉与忽略信号#include int sigaction(int sig,const struct sigaction *act, struct sigaction *oact);允许调用程序检查或指定与特

13、定信号相关的动作 signo:指定需求处置的特定信号 act:设定signo信号的处置动作 oact:保管此信号的当前处置动作例例1:#include main() static struct sigaction act; void catchint(int); act.sa_handler=catchint; sigfillset(&(act.sa_mask); sigaction(SIGINT,&act,NULL);printf(“sleep call #1 n);sleep(1);printf(“sleep call #2 n);sleep(1);printf(“sleep call #

14、3 n);sleep(1);printf(“sleep call #4 n);sleep(1);printf(“Exiting n);exit(0);void catchint(int signo) printf(“nCATCHINT:signo=%d n,signo); printf(“CATCHINT:returning n n);例例2:act.sa_handler=SIG_IGN;act.sa_handler=SIG_DFL;sigaction(SIGINT,&act,NULL);act.sa_handler=SIG_IGN;sigaction(SIGINT,&act,NULL);si

15、gaction(SIGQUIT,&act,NULL);例例3:static struct sigaction act,oact;sigaction(SIGTERM,NULL,&oact);act.sa_handler=SIG_IGN;sigaction(SIGTERM,&act,NULL);sigaction(SIGTERM,&oact,NULL);例例4:#include #include void g_exit(int s) unlink(“tempfile); fprintf(stderr,Interruptedexiting n); exit(1);extern void g_exit

16、(int);static struct sigaction act;act.sa_handler=g_exit;sigaction(SIGINT,&act,NULL);例例5:struct sigaction newact;newact.sa_handler=mysighand;newact.sa_flags=0;if(sigemptyset(&newact.sa_mask)=-1) |(sigaction(SIGINT,&newact,NULL)=-1) perror(“Failed to install SIGINT signal handler);例例6:struct sigaction

17、 act;if(sigaction(SIGINT,NULL,&act)=-1) perror(“Failed to get old handler for SIGINT);else if(act.sa_handler=SIG_DFL) act.sa_handler=SIG_IGN; if(sigaction(SIGINT,&act,NULL)=-1) perror(“Failed to ignore SIGINT); 例例7:void catchctrlc(int signo) char handmsg=“I found Ctrl-Cn; int msglen=sizeof(handmsg);

18、 write(STDERR_FILENO,handmsg,msglen);struct sigaction act;act.sa_handler=catchctrlc;act.sa_flags=0;if(sigemptyset(&act,sa_mask)=-1)|(sigaction(SIGINT,&act,NULL) perror(“Failed to set SIGINT to handle Ctrl-C);例例8:struct sigaction newact;newact.sa_handler=SIG_DFL;newact.sa_flags=0;if(sigemptyset(&newa

19、ct.sa_mask)=-1)|(sigaction(SIGINT,&newact,NULL)=-1) perror(“Failed to set SIGINT to the default action);例例9:#include #include int testignored(int signo) struct sigaction act; if(sigaction(signo,NULL,&act)=-1)| (act.sa_handler!=SIG_IGN) return 0; return 1;进程在收到大多数信号时所作的默许动作是使该进程正常终止,但有些信号会引起进程的非正常终止非

20、正常终止的进程系统默许的动作是:导出进程的内存映像core dump。即把进程在内存中的映像写入进程当前目录的下一个core文件中core文件会记住进程终止那一刻程序的各个变量值、硬件存放器值以及内核关于进程的控制信息有时在一个程序中收到信号,需求前往到先前设置的某个位置上。可以用两个比较特殊的函数来完成此义务用法表用法表#include int sigsetjmp(sigjmp_buf env,int savemask);void siglongjmp(sigjmp_buf env,int val); sigsetjmp和和siglongjmpsigsetjmp:经过保管进程堆栈环境来保管程

21、序的当前位置和信号掩码siglongjmp:把进程控制前往到sigsetjmp所保管的位置上 假设savemask非零,信号掩码的当前形状就被保管在缓冲区env中 程序直接调用sigsetjmp时前往0 siglongjmp中调用sigsetjmp前往val参数值例例1:#include #include #include #include sigjmp_buf position;main() static struct sigaction act; void goback(void); if(sigsetjmp(position,1)=0) act.sa_handler=goback; si

22、gaction(SIGINT,&act,NULL); domenu(); void goback(void) fprintf(stderr,nInterrupted n); siglongjmp(position,1);#include #include int ntimes=0;main() pid_t pid,ppid; void p_action(int),c_action(int); static struct sigaction pact,cact;pact.sa_handler=p_action;sigaction(SIGUSR1,&pact,NULL);switch(pid=fo

23、rk() case -1: perror(“synchro); exit(1); case 0: cact.sa_handler=c_action; sigaction(SIGUSR1,&cact,NULL); ppid=getppid();for(;) sleep(1);kill(ppid,SIGUSR1);pause();default: for(;) pause(); sleep(1); kill(pid,SIGUSR1); void p_action(int sig) printf(“Parent caught signal #%d n,+ntimes);void c_action(i

24、nt sig) printf(“Child caught signal #%d n,+ntimes);#include #include#define TIMEOUT 5#define MAXTRIES 5#define LINESIZE 100#define CTRL_G 007#define TRUE 1#define FALSE 0static int timed_out;static char answerLINESIZE;void catch(int sig) timed_out=TRUE; putchar(CTRL_G);char *quickreply(char *prompt) void catch(int); int ntries; static struct sigaction act,oact; act.sa_handler=catch; sigaction(SIGALRM,&act,&oact);for(ntri

温馨提示

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

评论

0/150

提交评论