信號能夠分爲兩大組:異步
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); }