信号概念:Linux系统响应某些状况而产生的事件,进程在接受到信号后采取相应的动作。
就比如说,当我们在写博客时,突然被某位朋友叫去帮忙,而停止了我们正在写博客这件事,而帮该朋友完后,我们再继续回来写博客。 而这个这位朋友叫我们,这就是信号。
在操作系统中,进程在受到某些信号的影响后,也会做出相应的动作,而信号有些是人为的,有些是系统为的。
产生信号:
1.键盘事件
2.非法内存
3.非法指令
在Linux下,可能通过 kill -l 指令看看信号:
信号的处理方式:
1.忽略 SIGKILL SIGSTOP (这两个信号不能忽略,因为它们向内核和超级用户提供了使进程终止或者停止的可靠方法. 另外,如果忽略某些由硬件异常产生的信号,则此进程的运行行为是未定义的.)
2.捕获并处理 SIGKILL SIGSTOP 不能捕获
3.缺省处理(由系统定义处理函数 可通过 man 7 signal 查看那些信号缺省处理做的是什么)
信号的分类:
1.不可靠信号:(1 - 31)
(1)Linux的信号处理继承来自UNIX,早起的UNIX当信号处理函数执行完毕后,该信号恢复成缺省处理动作,Linux已经改进,但是由于在UINX下,已经开发了太多的东西,已经不可能再把该默认恢复成缺省处理动作删除了。
(2)信号不排队,当某一时刻,几个信号传递过得时候,并没有处理完信号,导致了某些信号的丢失。
2.可靠信号:(34 - 64)
不会出现信号丢失
3.非实时信号
不可靠信号都是非实时信号
4.实时信号
可靠信号都是实时信号
注册信号:
void (*signal(int signum,void(*pf)(int)))(int);
void(*pf)(int)//自己定义的处理函数
发送信号:
kill(pid_t pid,int signum)
pid>0,明确的说给pid发送这个进程发送信号
pid=0,给本进程组的所以进程发送信号
pid==-1,给有权发送的所以进程发送信号
pid<-1,给|pid|进程组的任何一个进程发送信号
注册和发送信号代码:
1 #include<signal.h>
2 #include<unistd.h>
3 #include<stdio.h>
4 #include<stdlib.h>
5 #include<sys/types.h>
6
7 void handler(int s)
8 {
9 printf("recv %d\n",s);
10 exit(0);
11
12 }
13
14
15 int main()
16 {
17 signal(SIGUSR1,handler);
18 pid_t pid;
19 pid = fork();
20 if(pid == 0)
21 {
22 sleep(3);
23 kill(getppid(),SIGUSR1);
24 }else{
25 for( ; ; )
26 {
27 printf("1");
28 fflush(stdout);
29 sleep(1);
30 }
31 }
32 }
可重入和不可能重入函数:
条件:
1.函数内部调用了malloc或者free
2.调用了标准IO
3.使用了静态变量