信号被称为软中断(software interrupts),与硬件中断机制相比信号机制提供了更好
的灵活性:
-
产生源:
硬件中断:由硬件产生;
信号: 由内核/终端命令/用户进程产生; -
均打断当前代码的执行,转而执行另外的代码:
硬件中断: 跳转到中断函数;
信号: 跳转到信号处理函数; -
屏蔽位:
硬件中断: 可设置中断寄存器,屏蔽某些中断;有些中断无法屏蔽,被称为NMI中断.
信号: 可设置进程的信号屏蔽位,屏蔽某些信号;信号SIGSTOP/SIGKILL无法被屏蔽;
被屏蔽的硬件中断将丢失,而被屏蔽的信号不会丢失,但会覆盖。 -
执行时刻:
硬件中断: 产生后马上执行中断处理函数;
信号: 如果进程正在执行,那么立即执行信号处理函数,否则将在下次调度时执行; -
信号均有默认的处理函数;硬件中断没有,需在系统启动时进程初始化;
信号状态变迁:
Pending
Generated ----------------->Delivered
信号产生到处理函数响应之间的时间,处于Pending状态
信号分类:
- Standard signals: used by kernel to notify processes of events.
Standard signals are not queued;
On Linux, standard signals are numbered from 1 to 31; - Realtime signals;
Realtime signals are queued and delivered lowest signal number first;
Linux kernel defines 32 different realtme signals, numbered from 32 to 63;
The constants SIGRTMIN and SIGRTMAX to inicate lowest and highest available
realtime signal numbers;
信号数据结构:
sigset_t set;
int sigemptyset(sigset_t *set);
int sigfillset(sigset_t *set);
int sigaddset(sigset_t *set, int sig);
int sigdelset(sigset_t *set, int sig);
int sigismember(const sigset_t*set, int sig);
信号屏蔽:
int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
how:1> SIG_BLOCK: signal_mask |= set;
2> SIG_UNBLOCK: signal_mask ~= set;
3> SIG_SETMASK: signal_mask = set;
将参数set置为NULL,即可获取进程的信号屏蔽属性;
信号注册:
int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact);
sig: 除了SIGKILL/SIGSTOP信号之外;
struct sigaction
{
union {
void (*sa_handler)(int); // Address of handler
void (*sa_sigaction)(int, siginfo_t *, void*);
}__sigaction_handler;
sigset_t sa_mask; // Signals blocked during handler invocation
int sa_flags; // flags controlling handler invocation
void (*sa_restorer)(void); // Not for application use
};
#define sa_handler __sigaction_handler.sa_handler
#define sa_sigaction __sigaction_handler.sa_sigaction
sa_flag:
1>SA_NOCLDSTOP
2>SA_NOCLDWAIT
3>SA_NODEFER : 不再将信号本身加入到signal mask中;
4>SA_ONSTACK: 信号处理函数使用由sigaltstack()设置的栈;
5>SA_RESETHAND: When this signal is caught, reset its disposition to the default,
before invoking the handler.
6>SA_RESTART: Automatically restart system calls interrupted by this signal handler.
7>SA_SIGINFO: 指定信号处理函数采用如下原型:
void (*sa_sigaction)(int, siginfo_t *, void*);
如果该标志不置位,那么采用void (*sa_handler)(int)原型;
void handler(int sig, siginfo_t *siginfo, void *ucontext)
typedef struct {
int si_signo; // signal number
int si_code; // signal code
int si_trapno;
union sigval si_value; // Accompanying data from sigqueue()
pid_t si_pid; // Process ID of sending process
...
}siginfo_t;
向其它进程或自己发信号:
int kill(pid_t pid, int sig);
int raise(int sig);