硬件产生的信号:SIGBUS、SIGFPE、SIGILL、SIGSEGV
同步生成:信号的产生由进程本身的执行造成的 异步生成:引发信号产生的事件,与进程执行无关
linux内核按照信号编号的升序来传递信号。
(1)发送进程使用sigqueue()系统调用来发送信号及其伴随数据 (2)要为该信号建立一个处理器函数,接收进程应以SA_SIGINFO标志发起狂对sigaction()的调用。
#define _POSIX_C_SOURCE 199309 #include <signal.h> int sigqueue(pid_t pid, int sig, const union sigval value); //success 0; error -1t_sigqueue.c
#include <stdio.h> #include <signal.h> #include <stdlib.h> static int getInt(char *, char *); int main(int argc, char **argv){ pid_t pid; int sigNum, sigData, frequency, i; union sigval sv; if (argc < 4 || (argc > 1 && strcmp(argv[1], "--help") == 0)){ printf("usgae: %s pid sigNum sigData frequency\n", argv[0]); exit(EXIT_SUCCESS); } pid = (pid_t)getInt(argv[1], "pid of receive function"); sigNum = getInt(argv[2], "number of signal"); sigData = getInt(argv[3], "signal carrying value"); frequency = (argc > 4) ? getInt(argv[4], "Sending frequency") : 1; for (i = 0;i < frequency;i++){ sv.sival_int = sigData + i; if (sigqueue(pid, sigNum, sv) == -1){ printf("sigqueue() error!\n"); exit(EXIT_FAILURE); } } } static int getInt(char *p, char *msg){ int data; char *str; data = strtol(p, &str, 10); if (*str != '\0'){ printf("%s must be string\n", msg); exit(EXIT_FAILURE); }else if (data <= 0){ printf("%s must be greater than zero\n", msg); exit(EXIT_FAILURE); } return data; }catch_rtsigs.c
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <string.h> #include <unistd.h> static volatile sig_atomic_t flag = 0; static volatile int handler_sleepTime; static volatile int sigCount = 0; static int getInt(char *, char *); static void sigHandler(int, siginfo_t *, void *); int main(int argc, char **argv){ struct sigaction sa; int i, main_sleepTime; sigset_t blockMask, prevMask; if (argc != 3 || (argc > 1 && strcmp(argv[1], "--help") == 0)){ printf("usage: %s num1 num2\n" "\tnum1: sleep time for main function\n" "\tnum2: sleep time for sigHandler function\n", argv[0]); exit(EXIT_FAILURE); } printf("pid: %d\n", getpid()); sigfillset(&sa.sa_mask); sa.sa_flags = SA_SIGINFO; sa.sa_sigaction = sigHandler; for (i = 1;i < NSIG; i++){ if (i != SIGQUIT && i != SIGTSTP){ /* if (sigaction(i, &sa, NULL) == -1){ printf("sigaction() error!\n"); exit(-1); } */ sigaction(i, &sa, NULL); } } main_sleepTime = getInt(argv[1], "main sleep time"); handler_sleepTime = (argc > 2) ? getInt(argv[2], "handler sleep time") : 1; sigfillset(&blockMask); sigdelset(&blockMask, SIGINT); if (sigprocmask(SIG_SETMASK, &blockMask, &prevMask) == -1){ printf("sigprocmask() error!\n"); exit(EXIT_FAILURE); } sleep(main_sleepTime); printf("main function sleep complete\n"); sigprocmask(SIG_SETMASK, &prevMask, NULL); while (!flag) pause(); return 0; } static int getInt(char *p, char *msg){ char *ch; int data; data = strtol(p, &ch, 10); if (*ch != '\0'){ fprintf(stdout, "%s cannot be character\n", msg); exit(EXIT_FAILURE); }else if(data <= 0){ fprintf(stdout, "%s must be more than zero\n", msg); exit(EXIT_FAILURE); } return data; } static void sigHandler(int sig, siginfo_t *si, void *ucontext){ if (sig == SIGINT){ flag = 1; return; } sigCount++; printf("Caught signal %d: %s\n", sig, strsignal(sig)); printf("si_signo=%d, si_code=%d, ",si->si_signo, si->si_code); printf("si_pid=%ld, si_uid=%ld, ", (long)si->si_pid, (long)si->si_uid); printf("si_value=%d\n", si->si_value.sival_int); sleep(handler_sleepTime); }
t_sigsuspend.c
#define _GNU_SOURCE #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <string.h> #include <time.h> #include <errno.h> static volatile sig_atomic_t flag = 0; static void printSig(char *, char *); static void errExit(char *); static void sigHandler(int); int main(int argc, char **argv){ struct sigaction sa; sigset_t blockSig, prevSig; int i; time_t startTime; printSig("previous signal mask: ", "mask"); sigemptyset(&blockSig); sigaddset(&blockSig, SIGINT); sigaddset(&blockSig, SIGQUIT); if (sigprocmask(SIG_BLOCK, &blockSig, &prevSig) == -1){ errExit("siprocmask()"); } sa.sa_flags = 0; sa.sa_handler = sigHandler; sigemptyset(&sa.sa_mask); for (i = 1; i< NSIG; i++){ if (i == SIGINT || i == SIGQUIT){ sigaction(i, &sa, NULL); } } for (i = 1; !flag; i++){ printf("*********LOOP%d************\n", i); printSig("before the critical section, signal mask:", "mask"); for (startTime = time(NULL); time(NULL) < startTime + 4;) continue; printSig("the pending signal: ", "pending"); if (sigsuspend(&prevSig) == -1 && errno != EINTR){ errExit("sigsuspend()"); } } if (sigprocmask(SIG_SETMASK, NULL, &prevSig) == -1){ errExit("sigprocmask"); } printSig("At last, the signal mask:", "mask"); exit(EXIT_SUCCESS); } static void printSig(char *msg, char *mask){ int sig, num = 0; sigset_t sigSet; if (strcmp(mask, "mask") == 0){ if (sigprocmask(SIG_SETMASK, NULL, &sigSet) == -1) errExit("sigprocmask()"); }else{ if (sigpending(&sigSet) == -1) errExit("sigpending()"); } printf("%s", msg); for (sig = 1; sig < NSIG;sig++){ if (sigismember(&sigSet, sig)){ num++; printf("%d ", sig); } } if (!num) printf("empty set\n"); else printf("\n"); } static void errExit(char *msg){ printf("%s error\n", msg); exit(EXIT_FAILURE); } static void sigHandler(int sig){ if (sig == SIGQUIT){ flag = 1; return; } printf("signal %d: %s\n", sig, strsignal(sig)); }以同步方式等待信号
#define POSIX_C_SOURCE 199309 #include <signal.h> int sigwaitinfor(const sigset_t *set, siginfo_t *info); //success, signal; error, -1(1) sigwaitinfo()系统调用挂起进程的执行,直至set指向信号集中的某一信号抵达。 (2)调用sigwaitinfo(),需要先阻塞set中的信号
