信号能够分为两大组:异步
1,其值在SIGRTMIN和SIGRTMAX之间的实时信号。函数
2,全部其它信号。code
接下来有一个参数很关键,那就是接收某个信号的进程的sigaction调用中是否指定了新的SA_SIGINFO标志。队列
若是此标志指定了,那么实时信号的实时行为有保证,不然事实行为未指定,但对于通常信号来讲,不管此标志有无指定,实时行为都未指定。进程
那什么叫作实时行为呢?事件
事实行为有以下特征:it
1,信号是排队的,同一信号产生了三次,那么它就递交三次。io
2,当有多个SIGRTMIN到SIGRTMAX范围内的解阻塞信号排队时,值越小的优先权越高。class
3,当某个非实时信号递交时,传递给它的信号处理程序的惟一参数就是该信号的值;但对于实时信号来讲,它能够携带更多的信息。例如,经过SA_SIGINFO标志安装的实时信号的信号处理程序声明以下:test
void func(int signo, siginfo_t *info, void *content)
typedef struct { int si_signo; /*same value as signo argument*/ int si_code; /*SI_{USER,QUEUE,TIMER,ASYNCIO,MEGEQ}*/ union sigval si_value; /*integer or pointer value from sender*/ } siginfo_t;
4,一些新的函数定义成使用实时信号工做。例如,sigqueue函数代替kill函数。
上面讲到了si_code值,此值是用来代表此信号是由哪一个事件产生的,列表以下:
SI_ASYNCIO:信号是由某个异步I/O请求完成。
SI_MESGQ:信号是由一个消息放到一个空的队列上时产生的。
SI_QUEUE:信号是由sigqueue函数产生的。
SI_TIMER:信号是由使用timer_settime函数设置的某个定时器到时产生的。
SI_USER:信号是由kill函数产生的。
例子:该程序调用fork,子进程阻塞三种实时信号,父进程随后发送9个信号(三种实时信号中每种3个),子进程接着解阻塞信号,咱们查看每种信号各有多少个递交,以及递交顺序。
代码;
//rtsignals/test1.c
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> /* #define SIGRTMAX (sysconf(_SC_RTSIG_MAX)) #define SIGRTMIN (SYSCONF(_SC_RTSIG_MIN)) */ static void sig_rt(int, siginfo_t *, void *); typedef void sigfunc_rt(int, siginfo_t *, void *);//定义函数类型 sigfunc_rt *signal_rt(int, sigfunc_rt *, sigset_t *); int main(int argc, char **argv) { int i, j; pid_t pid; sigset_t newset; union sigval val; printf("SIGRTMIN = %d, SIGRTMIN = %d\n", (int) SIGRTMAX, (int) SIGRTMIN); if ((pid = fork()) == 0) { sigemptyset(&newset); sigaddset(&newset, SIGRTMAX); sigaddset(&newset, SIGRTMIN - 1); sigaddset(&newset, SIGRTMIN - 2); sigprocmask(SIG_BLOCK, &newset, NULL); signal_rt(SIGRTMAX, sig_rt, &newset); signal_rt(SIGRTMAX - 1, sig_rt, &newset); signal_rt(SIGRTMAX - 2, sig_rt, &newset); sleep(6); sigprocmask(SIG_UNBLOCK, &newset, NULL); sleep(3); exit(0); } sleep(3); for (i = SIGRTMAX; i >= SIGRTMAX - 2; i--) { for (j = 0; j <= 2; j++) { val.sival_int = j; sigqueue(pid, i, val); printf("sent signal %d, val = %d\n", i, j); } } exit(0); } static void sig_rt(int signo, siginfo_t *info, void *context) { printf("recei ved signal #%d, code = #%d, ival = %d\n", signo, info->si_code, info->si_value.sival_int); } sigfunc_rt *signal_rt(int signo, sigfunc_rt *func, sigset_t *mask) { struct sigaction act, oact; act.sa_sigaction = func; act.sa_mask = *mask; act.sa_flags = SA_SIGINFO; if ((sigaction(signo, &act, &oact)) < 0) return((sigfunc_rt *) SIG_ERR); return(oact.sa_sigaction); }