什么是信号:
信号是事件发生时对进程的通知机制,有时也称为软件中断。信号与硬件中断的相似之处在于打断了程序执行的正常流程,大多数情况下,无法预测信号到达的准确时间
信号源:
1.硬件
2.软件 (如ctrl+c 结束进程就是一个信号源)
常见的几种进程信号解释:
SIGHUP 关闭终端时会产生
SIGINT 按下ctrl+C 发送给进程的信号
SIGQUIT 按下ctrl+/ 发送给进程的信号
SIGILL 非法指令信号
SIGABRT c库函数中的abort产生的信号
SIGFPE浮点数异常
SIGSTOP 让进程暂停
SIGCONT 让进程继续
SIGPIPE 管道破裂的提示信号
信号是在PCB上写的,进程收到信号的三种响应:
1.忽略信号
2.捕获信号并处理(SIGKILL SIGSTOP 两种信号无法被忽略、无法被捕获处理)
3.缺省处理(缺省处理到底执行什么动作,可以用man 7 signal查看)
缺省处理:
TERM 缺省的动作是终止进程
IGN 忽略掉信号
Core 让进程终止并产生core文件
stop 让进程暂停
cont 让进程继续
信号的分类:
1.可靠信号和不可靠信号
不可靠表现在:
1.当执行完信号处理函数后恢复程缺省处理动作,解决方法在函数内部递归调用
2.当多个信号同时抵达,可能会出现信号丢失
1~31 不可靠信号 34~64:可靠信号
2.实时信号和非实时信号
34~64 为实时信号
实时信号与非实时信号没有快慢之分,区别就在于是否可靠
信号的具体操作:
安装/注册信号(当某个信号来时将如何处理):
void (*signal (int signo,void(*handler)(int)))(int)
signo: 要注册的信号
handler:信号处理函数
返回值为函数指针,成功返回的是旧的的信号处理函数,失败返回SIG_ERR
调用忽略信号函数:signal(SIGINT,SIG_IGN)
调用捕获信号函数:signal(SIGINT,SIG_DFL)
自定义处理函数:
1 #include<stdlib.h>
2 #include<stdio.h>
3 #include<unistd.h>
4 #include<signal.h>
5 void handler(int s)
6 {
7 printf("not kill");
8
9 }
10 int main()
11 {
12 signal(SIGINT,handler);
13 while(1)
14 {
15 sleep(1);
16 printf(" . ");
17 fflush(stdout);
18 }
19 }
发送信号:
kill命令
kill函数:
int kill(pid_t pid,int signo);
pid:给那个进程发送信号,如果pid为整数,则发送到指定进程。如果pid为0,则发送到本进程组中任何进程,如果pid=-1,发送给本进程有权发送的任何一个进程,如果pid<-1,给pid绝对值进程组中的任何一个进程,如pid=-5,则发送给进程组为5中的任何一个进程
signo:发送什么信号
返回值:成功0,失败-1
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<unistd.h>
4 #include<signal.h>
5 int main(int argc,char *argv[])
6 {
7 if(argc!=3)
8 {
9 fprintf(stderr,"usage:%s signo pid\n",argv[0]);
10 exit(1);
11 }
12 int sig=atoi(argv[1]);
13 int pid=atoi(argv[2]);
14 kill(pid,sig);
15 }
延时器:
int alarm(int sec);
sec :过sec秒后,信号SIGALRM抵达,若sec=0表示清除这个信号
返回值:为在alarm信号返回之前还剩下多少秒到达sec设定时间
可以用alarm做超时处理:
1 #include<stdlib.h>
2 #include<stdio.h>
3 #include<unistd.h>
4 int main()
5 {
6 alarm(3);
7 while(1)
8 {
9 printf(" . ");
10 fflush(stdout);
11 sleep(1);
12 }
13 }
定时器:
settitimer(int which,const struct itimerval *new_value,struct itimerval*old_value):
which:
ITIMER_REAL:真实时间,就是电脑桌面上显示的时间,到时间后会产生SIGALRM信号
ITIMER_VIRTUAL:虚拟时间,用户模式下执行的CPU时间,到时间后会产生SIGVTALRM
ITIMER_PROF:用户态和内核太CPU时间总和(也就是执行状态的时间),到时后会产生SIGPROF信号
old_value:返回先前设置的定时器,一般为NULL
struct itimerval{
struct timeval it_interval; //以后每次启动的间隔时间
struct timeval it_value; //第一次启动时间
};
struct timeval{
long tv_sec; //精确到秒
long tv_usec; //精确到微秒
}
当sec usec 都为0时表示永远都不启动
1 #include<stdlib.h>
2 #include<stdio.h>
3 #include<unistd.h>
4 #include<sys/time.h>
5 #include<signal.h>
6 #include<string.h>
7 void handler(int s)
8 {
9 printf("time out %d\n",s);
10 }
11 int main()
12 {
13 signal(SIGALRM,handler);
14 struct itimerval it;
15 memset(&it,0x00,sizeof(it));
16 it.it_value.tv_sec=0;
17 it.it_value.tv_usec=1;
18 it.it_interval.tv_sec=1;
19 setitimer(ITIMER_REAL,&it,NULL);
20 for(;;)
21 {
22 printf(" . ");
23 fflush(stdout);
24 sleep(1);
25 }
26 }