发送和捕获信号
# 发送和捕获信号
发送信号:进程可以使用系统调用kill()
向另一个进程或者进程组发送信号。
捕获信号:进程可以使用系统调用signal()
或者sigaction()
来安装信号处理函数来捕获特定的信号,本篇文章主要介绍signal()
。
# 信号处理函数
程序可以用signal库函数来处理信号:
#include <signal.h>
void (*signal( int sig, void (*func)(int)))(int);
1
2
2
signal是一个带有sig和func两个参数的函数,准备捕获或忽略的信号由参数sig给出,接收到指定的信号后将要调用的函数由func给出。
信号处理函数必须有一个int类型参数(即接收到的信号代码),并且返回值为void*。
signal函数本身也返回一个同类型的函数(指针),即先前用来处理这个信号的函数。
func取值也可为下列两个宏:
SIG_IGN:忽略信号
SIG_DFL:恢复默认行为
# signal函数举例
# 响应控制台信号
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
void sig_alarm(int sig)
{
printf("---the signal received is %d. \n", sig);
signal(SIGINT, SIG_DFL);
}
int main()
{
signal(SIGINT, sig_alarm);
while(1)
{
printf("waiting here!\n");
sleep(1);
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
- 编写程序,它将响应用户敲入的组合键ctrl+c,在屏幕上打印出一条适当的消息,而不是终止程序,当用户第二次按下此组合键时,终止程序。
# 发送信号
- 进程可以通过调用kill函数向包括它本身在内的其他进程发送一个信号。
- 要想发送一个信号,发送进程必须拥有相应的权限,通常两个进程必须拥有相同的用户ID,进程只能发送信号给属于同一个用户的其他进程。
- kill调用失败可能的原因:
- 给定的信号无效
- 发送进程权限不够
- 目标进程不存在。
# 示例代码
#include <signal.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
static int alarm_fired = 0;
void ding(int sig)
{
alarm_fired = 1;
}
int main()
{
int pid;
printf("alarm application starting\n");
if((pid = fork()) == 0)
{
sleep(5);
kill(getppid(), SIGALRM);
exit(0);
}
printf("waiting for alarm to go off\n");
signal(SIGALRM, ding);
//suspend until a signal is received
//pause() shall return after the signal-catching function returns.
pause();
if (alarm_fired)
printf("Signal is received!\n");
printf("done\n");
exit(0);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 输出
alarm application starting
waiting for alarm to go off
Signal is received!
done
1
2
3
4
2
3
4
# 分析
这段代码是一个使用pause()
函数等待信号的程序。程序会创建一个子进程,在5秒后向父进程发送SIGALRM
信号,父进程等待信号并在收到信号后输出一条信息。
编辑 (opens new window)
上次更新: 2023/02/19, 10:48:02
- 01
- Linux系统移植(五)--- 制作、烧录镜像并启动Linux02-05
- 03
- Linux系统移植(三)--- Linux kernel移植02-05