1. 信号的基本信息
通过man 7 signal
可以查看信号的详细信息。
每一个信号都有一个默认的处理动作,决定了进程接受到该信号后如何处理。信号的5种默认处理动作:
- Term 终止进程
- Ign 当前进程忽略掉这个信号
- Core 终止进程,并生成一个Core文件
- Stop 暂停当前进程
- Cont 继续执行当前被暂停的进程
各个信号的默认行为如上图。其中SIGKILL和SIGSTOP不能被捕捉、堵塞和忽略。
2. kill函数
函数说明:给进程发送信号
头文件:
#include <sys/types.h>
#include <signal.h>
函数原型:
int kill(pid_t pid, int sig);
函数参数:
pid—进程号或者某个进程组的编号。
- 如果该值是正数,代表信号发给某个进程;
- 如果该值是0,代表信号发给调用该函数的进程所在组的其他所有进程。
- 如果该值是-1,信号发送给该进程允许发送的所有进程,除了进程1(init)。
- 如果该值小于-1,该信号发送给进程组ID为-pid内的所有进程。
sig—信号的编号或者宏值。
如果信号的值为0,不会发送任何信号,可以用来检查该进程ID或进程组ID是否存在。
返回值:
如果至少一个信号被发送成功,返回0;如果错误返回-1,并且全局变量errno被设置成相应的值。
3. raise函数
函数说明:给调用者发送一个信号,等价于kill(getpid(), sig)
。
头文件:
#include <signal.h>
函数原型:
int raise(int sig);
函数参数:
sig—信号的编号或者宏值。
返回值:
成功返回0,失败返回非0.
4. abort函数
函数说明:发送SIGABRT信号(值为6)给当前进程,杀死当前进程。
头文件:
#include <stdlib.h>
函数原型:
void abort(void);
等价于kill(getpid(), SIGABRT)
。
5. alarm函数
函数说明:安排一个定时器,到时间了给进程发一个alarm信号。每一个进程都有且只有唯一的一个定时器。该函数只能定时一次。
头文件:
#include <unistd.h>
函数原型:
unsigned int alarm(unsigned intseconds);
函数参数:
这个函数会在指定的seconds秒后产生一个SIGALRM信号给当前进程。该信号的默认动作是终止进程。
如果参数为0,代表任何定时器都无效(包括之前设置的定时器)。
返回值:
- 之前有定时器,返回之前的定时器的剩余时间
- 之前没有定时器,返回0
alarm(5); //返回0
sleep(2);
alarm(6); //返回3,重新从0开始数秒
6.setitimer函数
函数说明:设置内部定时器的值,替代alarm函数。精度为微秒,可实现周期性定时。
头文件:
#include <sys/time.h>
函数原型:
int setitimer(int which, const struct itimerval *restrict value,struct itimerval *restrict ovalue);
函数参数:
which取值:ITIMER_PROF、 ITIMER_REAL、TIMER_VIRTUAL。
- ITIMER_PROF:以真实时间为准,到时间后产生SIGALRM,一般使用真实时间作为定时器基准;
- TIMER_VIRTUAL:虚拟定时器,以用户模式CPU消耗时间为准,包括进程内所有线程消耗的时间。也就是没有将内核时间、IO调用时间算上。时间到后产生SIGVTALRM信号。
- ITIMER_PROF:以用户和内核消耗的CPU总时间为准。时间到后产生SIGPROF信号。
new_value:设置定时器的属性。
//定时器结构体
struct itimerval {
struct timeval it_interval; //定时事件
struct timeeval it_value; //延迟多长时间启动定时器
}
//时间结构体
struct timeval {
time_t tv_sec; //秒
suseconds_t tv_user;//微秒
}
new_value:记录上一次定时器的属性,一般指定NULL,不使用。
返回值:
成功返回0,失败返回-1.
struct itimerval new_value;
//设置2秒定时
new_value.it_interval.tv_sec = 2;
new_value.it_interval.tv_usec = 0;
//设置3秒后启动定时器
new_value.it_value.tv_sec = 3;
new_value.it_valuel.tv_usec = 0;
setitimer(TIMEER_REAL, &new_value, NULL); //非阻塞