Linux--信号编程
l信号
对中断机制的一种模拟:异步通信方式
任何时候可发给某一进程,无需知道该进程的状态
不可靠信号(非实时信号)
可靠信号(实时信号)
所有可靠信号都支持排队,所有不可靠信号都不支持排队
信号生命周期
•信号产生
•信号在进程中注册
•信号在进程中注销
•执行信号处理函数
用户进程对信号的响应
执行缺省操作,Linux对每种信号都规定了默认操作
忽略信号,即对信号不做任何处理,
有两个信号不能忽略:SIGKILL及SIGSTOP。
捕捉信号
•定义信号处理函数
•当信号发生时,执行相应的自定义处理函数。
四个函数
kill()
•发送信号给进程/进程组
•不仅可以中止进程(发SIGKILL信号),也可以向进程发送其他信号
•是kill()函数的一个用户接口
raise()
•允许进程向自身发送信号
eg. 该例子完成以下功能:子进程向自身raise一个SIGTOP信号,使自身暂停;父进程kill子进程。
View Code
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <sys/types.h>
4 #include <sys/wait.h>
5 #include <signal.h>
6
7 int main() {
8 pid_t pid;
9 int ret;
10
11 if ((pid=fork())<0) {
12 printf("Fork error!\n");
13 exit(1);
14 } else if (pid==0) {
15 printf("Child %d is waiting for signal...\n",getpid());
16 // 子进程向自身发送一个SIGTOP信号,用于暂停进程
17 raise(SIGSTOP);
18 // 由于在暂停过程中,被父进程kill掉,于是下面的代码均不会运行。
19 printf("I am killed, bye!\n");
20 exit(0);
21 } else {
22 sleep(3);
23 // wait子进程且以不阻塞形式,若子进程未exit,则返回0
24 if ((waitpid(pid,NULL,WNOHANG))==0) {
25 // 向子进程发送SIGKILL信号,无论子进程是否阻塞、处理,都将结束
26 if ((ret=kill(pid,SIGKILL))==0) {
27 printf("Parent kill child %d!\n",pid);
28 }
29 }
30 // wait子进程,以阻塞方式
31 waitpid(pid,NULL,0);
32 exit(0);
33 }
34
35 }
alarm()
•在进程中设置一个定时器,当定时器指定的时间到时,它就向进程发送SIGALARM信号
•一个进程只能有一个闹钟时间
–如果在调用alarm()之前已设置过闹钟时间,则任何以前的闹钟时间都被新值所代替
pause()
•将调用进程挂起直至捕捉到信号为止
•通常用于判断信号是否已到
eg.
View Code
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 int main() {
6 int ret=alarm(5);
7 // ret返回0
8 printf("alarm return: %d.\n",ret);
9 // 阻塞当前进程,直到收到信号
10 // 这里会收到alarm信号
11 pause();
12 printf("Wake up!\n");
13 }
View Code
1 #include <unistd.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4
5 int main() {
6 int ret=alarm(5);
7 // ret返回0
8 printf("alarm return %d\n",ret);
9 sleep(2);
10 // ret返回3
11 ret=alarm(5);
12 printf("alarm return %d\n",ret);
13 pause();
14 printf("Wake up!\n");
15 }
SIGALRM信号默认是终止,所以最后的‘wake up’并没有执行。