接着上一篇博客对信号的介绍,本篇来介绍一下常用的接个信号和一些要点:
linux信号分为非可靠信号(unix继承而来)与可靠信号(linux自身拓展)。linux信号有62个,我们很难记住所有信号,此时我们会记一些常见的信号,其余的在遇到时去查也是很快的,下面将介绍几种常见的信号:
SIGINT:键盘中断信号(Ctrl+C)
SIGQUIT:键盘退出信号(Ctrl+\)
SIGHUP:终端结束信号
SIGPIPE:浮点异常信号
SIGKILL:用来结束进程的信号
SIGALARM:定时器信号
SIGCHLD:表示子进程退出的信号,可告知父进程子进程退出
SIGTERM:kill命令发出的信号
SIGSTOP:停止执行信号(Ctrl+Z)
-
废话不多说,接下来直接将上一篇博客的内容在这篇博客中演示一下:
- kill、abort、alarm、raise、sigqueue演示:
#include<stdio.h> #include<stdlib.h> #include<signal.h> #include<errno.h> #include<fcntl.h> #include<sys/types.h> int main() { //1.下面这段damo用于测试alarm /* int ret = 0; ret = alarm(3); sleep(2); printf("ret = %d\n",ret); ret = alarm(2); sleep(1); printf("ret = %d\n",ret); ret = alarm(0); printf("ret = %d;alarm(0)将前面的闹钟取消了!\n",ret); return 0; */ //2.这段damo用于测试kill函数 /*pid_t pid = -1; pid = fork(); if(pid > 0) { //父进程在10秒后通过kill发送SIGINT信号杀死子进程 sleep(10); kill(pid,SIGINT); printf("子进程已经被我杀掉了!!!\n"); return 0; } else if( pid == 0) { while(1) { printf("啦啦啦啦啦啦!!!\n"); sleep(1); } }*/ //3.这段damo将用于测试raise函数 /*pid_t pid = -1; pid = fork(); if(pid > 0) { //子进程将在10秒后自杀,父进程wait子进程为其收尸 printf("请等待10秒数......\n"); wait(pid); printf("已经为子进程收尸!!!\n"); return 0; } else if( pid == 0) { sleep(10); raise(SIGBUS); }*/ //4.这段damo演示abort函数 /*pid_t pid; pid = fork(); if(pid<0) { perror("fork error!\n"); return -1; } if(pid == 0) { printf(" i am child!\n"); abort(); //abort函数等同于kill(getpid(),SIGABRT); } wait(NULL); printf("child call abor\n"); return 0;*/ //5.这段damo将演示sigqueue函数 pid_t pid = -1; pid = fork(); if(pid<0) { printf("fork error!\n"); return -1; } union sigval val; if(pid == 0) { printf(" i will call sigqueue send SIGKILL\n"); sigqueue(getpid(),SIGKILL,val); } wait(NULL); printf("child call sigqueue!\n"); return 0; }
- 处理信号的三种方式:默认处理方式、自定义处理方式、忽略处理
老式处理方式接口signal使用样例:
但是signal函数可能会出现一些问题,我们习惯上去使用sigactoin函数:#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<fcntl.h> #include<signal.h> void sig_handler(int sig_no) { if(SIGINT == sig_no) { printf("\nGet(Ctrl+C)\n"); } if(SIGQUIT == sig_no) { printf("\nGet(Ctrl+\\)\n"); } if(SIGABRT == sig_no) { printf("\nGet SIGABRT\n"); } else ; } int main() { printf("enter for signal....\n"); sleep(2);//等待信号的出现 //Ctrl+C signal(SIGINT,sig_handler); //异常终止 signal(SIGABRT,sig_handler); //Ctrl+'\' signal(SIGQUIT,sig_handler); pause(); return 0; }
#include<stdio.h> #include<unistd.h> #include<sys/types.h> #include<signal.h> #include<stdlib.h> #include<string.h> void sig_handler(int sig_no) { if(SIGINT == sig_no) { printf("\nGet(Ctrl+C)\n"); } if(SIGQUIT == sig_no) { printf("\nGet(Ctrl+\\)\n"); } if(SIGABRT == sig_no) { printf("\nGet SIGABRT\n"); } else ; } int main() { printf("wait for signal...\n"); struct sigaction act; //初始化信号结构 memset(&act,0,sizeof(act)); //设置信号处理函数 act.sa_handler = sig_handler; act.sa_flags = 0; //注册信号SIGINT if(sigaction(SIGINT,&act,NULL)<0) { perror("sigaction"); return -1; } //注册信号SIGQUIT if(sigaction(SIGQUIT,&act,NULL)<0) { perror("sigaction"); return -1; } pause(); return 0; }
- 处理信号的三种方式:默认处理方式、自定义处理方式、忽略处理
- kill、abort、alarm、raise、sigqueue演示: