信号的产生函数和自定义捕捉函数
自定义捕捉函数
函数原型:
#include <signal.h>
typedef void (*sighandler_t)(int);
sighandler_t signal(int signum, sighandler_t handler);
参数解释
- signum: 需要捕获的信号。
- handler: 由上可以看到,handler是一个返回值为void,参数为Int的函数指针。此函数就是我们捕捉后要执行的处理函数。
返回值
-
成功调用,返回值为上一次的信号处理函数指针。如上一次未设置,就是返回默认的行为。可以用来保护现场,恢复上一次的捕获行为。
-
失败调用SIG_ERR。并且正确设置errno.
kill函数
函数原型:
#include <sys/types.h>
#include <signal.h>
int kill(pid_t pid, int sig);
用来给指定进程会进程组发送信号的函数。
参数解释
- pid: 有以下情况。
- pid > 0: 发送信号给指定的进程。
- pid = 0: 发送信号给 与调用kill函数进程属于同一进程组的所有进程。
- pid < 0: 取|pid|发给对应进程组。
- pid = -1:发送给进程有权限发送的系统中所有进程。
- sig: 要发送的信号。
返回值
- 成功调用返回0.
- 失败调用返回-1,且设置errno。
raise和bort函数
raise函数
函数原型:
#include <signal.h>
int raise(int sig);
给调用它的进程发信号。如果该信号被捕捉,捕捉返回了之后raise函数才会返回。
成功调用返回0,失败返回非零值。
sig就是指定的信号。
abort函数
函数原型:
#include <stdlib.h>
void abort(void);
杀死该进程。发出SIGABRT信号。
alarm函数
函数原型:
#include <unistd.h>
unsigned int alarm(unsigned int seconds);
经过second秒之后,发出SIGALRM信号,alarm信号默认终止进程。
一个进程只能有一个时钟,如果新设置了,旧的那个不再起作用。
参数解释
seconds:定时的秒数。
返回值
- 之前没设置过时钟:返回0.
- 之前设置过时钟:返回上一次设置剩余的秒数。
setitimer函数
函数原型:
#include <sys/time.h>
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
其中,struct itimerval结构体为:
struct itimerval {
struct timeval it_interval; /* next value */
struct timeval it_value; /* current value */
};
struct timeval {
time_t tv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
setitimer也是一个定时函数,相比alarm功能更强大,提供微妙精确,且可以进行周期定时。
参数解释
-
which: 指定计时方式。
- 自然定时:ITIMER_REAL → SIGLARM。
- 虚拟空间计时(用户空间):ITIMER_VIRTUAL → SIGVTALRM。计算进程占用的CPU时间。
- 运行时计时(用户+内核):ITIMER_PROF → SIGPROF。 计算占用cpu及执行系统调用的时间。
-
new_value: 定时的时间。此结构体中的成员:
- it_interval: 周期时间值。
- it_value: 下次执行的时间。
而timeval结构体就是时间值,tv_sec是秒,tv_usec是微妙。
-
old_value: 作为一个传出参数,传出上次传入的结构体。用于保护现场。
setitimer应用实例
void SigAction(int signal)
{
printf("Get signal:%d\n", signal);
}
int main()
{
struct itimerval itimer = {{3,0},{5,0}};
setitimer(ITIMER_REAL, &itimer, NULL);
signal(SIGALRM, SigAction);
while(1)
{
printf("come to get a signal!\n");
sleep(1);
}
return 0;
}
此函数运行之后,第一次5秒后触发,发出SIGALRM。我们自定义函数捕获到SIGALRM之后会执行SigAction函数内容。随后,每隔3秒都会触发一次。