Linux系统编程学习笔记(九)信号管理2
信号2:
1、信号集合:
信号集合以及其操作我们经常遇到,比如设置一些进程要阻塞的信号,进程的信号pending集合。
以下是常用的信号操作:
#include <signal.h>int sigemptyset(sigset_t *set);int sigfillset(sigset_t *set);int sigaddset(sigset_t *set, int signo);int sigdelset(sigset_t *set, int signo);int sigismember(const sigset *set, int signo);
#include <signal.h>int sigisemptyset(sigset_t *set);int sigorset(sigset_t *dest, sigset_t *left, sigset_t *right);int sigandset(sigset_t *dest, sigset_t *left, sigset_t *right);
#include <signal.h>int sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
#include <signal.h>#include <unistd.h>#include <stdio.h>void pr_mask(const char *str){sigset_t sigset;int errno_save;errno_save = errno;if(sigprocmask(0,NULL,&sigset) < 0){perror("sigprocmask");return 1;}printf("%s",str);if(sigismember(&sigset,SIGINT)) printf("SIGINT");if(sigismember(&sigset,SIGQUIT)) printf("SIGQUIT");if(sigismember(&sigset,SIGUSR1)) printf("SIGUSR1");if(sigismember(&sigset,SIGALARM)) printf("SIGALARM");printf("\n");errno = errno_save;}#include <signal.h>int sigpending(sigset_t *set);
#include <signal.h>#include <unistd.h>#include <stdio.h>stati void sig_quit(int);int main(void){sigset_t newmask,oldmask,pendmask;if(signal(SIGQUIT,sig_quit) == SIG_ERR){perror("signal");return 1;}sigemptyset(&newmask);sigaddset(&newmask,SIGQUIT);if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) < 0){perror("sigprocmask");return 1;}sleep(5);if(sigpending(&pendmask) < 0){perror("sigprocmask");return 1;}if(sigismember(&pendmask,SIGQUIT)){printf("\nSIGQUIT pending\n");return 1;}if(sigprocmask(SIG_SETMASK,&oldmask,NULL) < 0){perror("sigprocmask");return 1;}printf("SIGQUIT unblocked\n");sleep(5);exit(0);}static void sig_quit(int signo){printf("caught SIGQUIT\n");if( signal(SIGQUIT, SIG_DEL) == SIG_ERR)perror("SIGQUIT");}sigset_t newmask, oldmask;sigemptyset(&newmask);sigaddset(&newmask,SIGINT);if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) < 0){perror("sigprocmask");return 1;}/* critical region of code*//* reset signal mask, whick is unblocks SIGINT */if(sigprocmask(SIG_SETMASK,&oldmask,NULL) < 0){perror("sigprocmask");return 1;}/* wait for signal to occur */pause();#include <signal.h>int sigsuspend(const sigset_t *set);
#include <unistd.h>#include <signal.h>#include <stdio.h>static void sig_int(int);int main(void){sigset_t newmask,oldmask,waitmask;pr_mask("program start:");//前面我们定义的打印信号掩码的函数if(signal(SIGINT, sig_int) == SIG_ERR){perror("signal");return 1;}sigemptyset(&waitmask);sigaddset(&waitmask,SIGUSR1);sigemtpyset(&newmask);sigaddset(&newmask,SIGINT);/* block SIGINT and save current signal mask */if(sigprocmask(SIG_BLOCK,&newmask,&oldmask) < 0){perror("sigprocmask");return 1;}pr_mask("in critical region: ");/* pause, allowing all signals except SIGUSR1. */if(sigsuspend(&waitmask) != -1){perror("sigsuspend");return 1;} pr_mask("after return from sigsuspend:");/* reset signal mask with unblock SIGINT */if(sigmaskproc(SIG_SETMASK,&oldmask,NULL) < 0){perror("sigmaskproc");return 1;}pr_mask("program exit:");exit(0);}#include <signal.h>int sigaction(int signo, const struct sigaction *act, struct sigaction *oldact);
struct sigaction{void (*sa_handler)(int); /*addr of signal handler */void (*sa_sigaction)(int siginfo_t *, void *);/* alternate handler */sigset_t sa_mask; /*signals to block */int sa_flags; /* flags */void (*sa_restorer)(void); /* obsolete and non-POSIX */};void my_handler(int signo);
void my_handler(int signo, siginfo_t *si, void *ucontext);
#include <signal.h>SigFunc * signal(int signo,SigFunc * func){struct sigaction act,oact;act.sa_handler = func;sigemptyset(&act.sa_mask);act.sa_flags = 0;if(signo == SIGALARM){#ifdef SA_INTERRUPTact.sa_flag |= SA_INTERRUPT;#endif}else{#ifdef SA_RESTARTact.sa_flag |= SA_RESTART;#endif}if(sigaction(signo,&act,&oact) < 0)return SIG_ERR;return (oact.sa_handler);}#include <signal.h>int sigqueue(pid_t pid, int signo, const union sigval value);
union sigval{int sival_int;void *sival_ptr;},sigval value;int ret;value.sival_int = 404;ret = sigqueue(1722,SIGUSR2,value);if(ret)perror("sigqueue");#include <stdlib.h>void abort(void)
#include <signal.h>#include <stdio.h>#include <stdlib.h>#include <unistd.h>void abort(void){sigset_t mask;struct sigaction action;/* Caller can't ignore a SIGABRT, if so reset to default */sigaction(SIGABRT,NULL,&action);if(&action.sa_handler == SIG_IGN){action.sa_handler = SIG_DFL;sigaction(SIGABRT,&action,NULL);}if(action.sa_handler == SIG_DFL){fflush(NULL);/* flush all open stdio stream */}/* caller can't block SIGABRT; make sure it's unblocked */sigfillset(&mask);sigdelset(&mask,SIGABRT);sigprocmask(SIG_SETMASK,&mask,NULL);kill(getpid(),SIGABRT);/* If we're here,process caught SIGABRT and returned */ /* 如果信号被捕获,返回之后需要将handler设置为SIG_DFL,保证调用abort会终止进程*/fflush(NULL); /* flush all open stdio stream */action.sa_handler = SIG_DFL;sigaction(SIGABRT,&action, NULL); /* reset to default */sigprocmask(SIG_SETMASK,&mask,NULL);/* just in case ...*/kill(getpid(),SIGABRT);/* and one more time ...*/exit(1);}