信号机制
信号是在软件层次上对中断机制的一种模拟,是一种异步通信方式;
linux内核通过信号通知用户进程,不同的信号类型代表不同的事件;
Linux对早期的unix信号机制进行了扩展;
进程对信号有不同的响应方式:缺省方式,忽略信号,捕捉信号;
信号的产生
按键产生
系统调用函数产生(比如raise,kill)
硬件异常
命令行产生 (kill)
软件条件(比如被0除,访问非法内存等)
常用的信号
信号相关的命令(kill/killall)
kill [-signal] pid
默认发送SIGTERM
-sig 可指定信号
pid指定发送对象
killall [-uuser | prog]
prog指定进程名
user指定用户名
信号发送(kill/raise)
#include<unistd.h>
#include <signal.h>
int kill(pid_t pid,int sig);
int raise(int sig); //给自己发信号
成功时返回0,失败时返回EOF;
pid 接收进程的进程号; 0代表同组进程; -1代表所有进程;
sig 信号类型
定时器
unsigned int alarm(unsigned int seconds);
功能:定时发送SIGALRM给当前进程
参数:seconds:定时秒数
返回值:上次定时剩余时间。
ualarm(循环发送)
useconds_t ualarm(useconds_t usecs, useconds_t interval);
以useconds为单位,第一个参数为第一次产生时间,第二个参数为间隔产生
int setitimer(int which, const struct itimerval *new_value, struct itimerval *old_value);
功能:定时的发送alarm信号
参数:which:
ITIMER_REAL:以逝去时间递减。发送SIGALRM信号
ITIMER_VIRTUAL:计算进程(用户模式)执行的时间。发送SIGVTALRM信号
ITIMER_PROF:进程在用户模式(即程序执行时)和核心模式(即进程调度用时)均计算时间。发送SIGPROF信号
new_value:负责设定timout时间
old_value:存放旧的timeout值,一般指定为NULL
struct itimerval {
struct timeval it_interval; //闹钟触发周期
struct timeval it_value; //闹钟触发时间
};
struct timeval {
time_ttv_sec; /* seconds */
suseconds_t tv_usec; /* microseconds */
};
信号的捕捉
信号捕捉过程
1.定义新的信号的执行函数handle。
2.使用signal/sigaction函数,把自定义的handle和指定的信号相关联。
signal函数
typedef void (*sighandler_t)(int);
sighandler_tsignal(int signum, sighandler_t handler);
功能:捕捉信号执行自定义函数
返回值:成功时返回原先的信号处理函数,失败时返回SIG_ERR
参数:
signum要设置的信号类型
handler指定的信号处理函数: SIG_DFL代表缺省方式; SIG_IGN代表忽略信号;
系统建议使用sigaction函数,因为signal在不同类unix系统的行为不完全一样。
sigaction函数
int sigaction(int signum, const struct sigaction *act,struct sigaction *oldact);
struct sigaction {
void (*sa_handler)(int);
void (*sa_sigaction)(int, siginfo_t *, void *);
sigset_t sa_mask;int sa_flags;
void (*sa_restorer)(void);
};
参数:
signum:处理的信号
act,oldact:处理信号的新行为和旧的行为,是一个sigaction结构体。sigaction结构体成员定义如下:
sa_handler:是一个函数指针,其含义与signal函数中的信号处理函数类似
sa_sigaction:另一个信号处理函数,它有三个参数,可以获得关于信号的更详细的信息。
sa_flags参考值如下:
SA_SIGINFO:使用sa_sigaction成员而不是sa_handler作为信号处理函数
SA_RESTART:使被信号打断的系统调用自动重新发起。
SA_RESETHAND:信号处理之后重新设置为默认的处理方式。
SA_NODEFER:使对信号的屏蔽无效,即在信号处理函数执行期间仍能发出这个信号。re_restorer:是一个已经废弃的数据域;
使用SIGCHLD信号实现回收子进程
SIGCHLD的产生条件:
1子进程终止时
2子进程接收到SIGSTOP信号停止时
3子进程处在停止态,接受到SIGCONT后唤醒时