- 部分内核宏及函数对照
/*signal number*/ #define SIGHUP 1 #define SIGINT 2 #define SIGQUIT 3 #define SIGILL 4 #define SIGTRAP 5 #define SIGABRT 6 #define SIGIOT 6 #define SIGBUS 7 #define SIGFPE 8 #define SIGKILL 9 #define SIGUSR1 10 #define SIGSEGV 11 #define SIGUSR2 12 #define SIGPIPE 13 #define SIGALRM 14 #define SIGTERM 15 #define SIGSTKFLT 16 #define SIGCHLD 17 #define SIGCONT 18 #define SIGSTOP 19 #define SIGTSTP 20 #define SIGTTIN 21 #define SIGTTOU 22 #define SIGURG 23 #define SIGXCPU 24 #define SIGXFSZ 25 #define SIGVTALRM 26 #define SIGPROF 27 #define SIGWINCH 28 #define SIGIO 29 #define SIGPOLL SIGIO /* #define SIGLOST 29 */ #define SIGPWR 30 #define SIGSYS 31 #define SIGUNUSED 31 /* 这些不应该被考虑 */ #define SIGRTMIN 32 #ifndef SIGRTMAX #define SIGRTMAX _NSIG #endif /*int sa_flags*/ #define SA_NOCLDSTOP 0x00000001 #define SA_NOCLDWAIT 0x00000002 #define SA_SIGINFO 0x00000004 #define SA_ONSTACK 0x08000000 #define SA_RESTART 0x10000000 #define SA_NODEFER 0x40000000 #define SA_RESETHAND 0x80000000 #define SA_NOMASK SA_NODEFER #define SA_ONESHOT SA_RESETHAND /********************************/ #define __BITS_PER_LONG 32 #define _NSIG 64 #define _NSIG_BPW __BITS_PER_LONG #define _NSIG_WORDS (_NSIG / _NSIG_BPW) /*sigset_t结构体*/ typedef struct { unsigned long sig[_NSIG_WORDS]; /* unsigned long sig[2];*/ } sigset_t; /*sigaction结构体*/ struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }; /*how值*/ #ifndef SIG_BLOCK #define SIG_BLOCK 0 /* for blocking signals */ #endif #ifndef SIG_UNBLOCK #define SIG_UNBLOCK 1 /* for unblocking signals */ #endif #ifndef SIG_SETMASK #define SIG_SETMASK 2 /* for setting the signal mask */ #endif /*handler提供的三种信号处理方式*/ #define SIG_DFL ((__sighandler_t)0) /* 系统默认处理信号 */ #define SIG_IGN ((__sighandler_t)1) /* 忽略该信号 */ #define SIG_ERR ((__sighandler_t)-1) /* 从信号返回错误 */ /* 标准文件描述符 */ #define STDIN_FILENO 0 /* Standard input. */ #define STDOUT_FILENO 1 /* Standard output. */ #define STDERR_FILENO 2 /* Standard error output. */ ```
- 例子:
/*1.部分信号处理举例*/ #include <stdio.h> #include <stdlib.h> #include <signal.h> /** * 函数名:sa_quit_handler * 描述: 用户自定义SIGQUIT、SIGTSTP信号处理函数 * 参数: int signo -- 响应的信号 * 返回值:nonu */ void sa_user_handler(int signo){ if(SIGQUIT == signo){ fprintf(stderr, "rec: SIGQUIT\n"); }else if(SIGTSTP == signo){ fprintf(stderr, "rec: SIGTSTP\n"); } } /*ctrl + z : 从键盘发送SIGTSTP信号给进程,暂停进程*/ /*ctrl + \ : 从键盘发送SIGQUIT信号给进程,进程退出*/ /*ctrl + c : 终止进程*/ int main(void){ struct sigaction act; sigset_t register_mask; sigemptyset(®ister_mask); //清空sigset_t结构体 sigaddset(®ister_mask, SIGQUIT|SIGTSTP); /*添加要阻塞的信号*/ sigprocmask(SIG_BLOCK, &act.sa_mask, NULL); /*注册信号处理函数前阻塞SIGQUIT、SIGTSTP信号*/ /*注册SIGQUIT信号处理函数部分*/ sigemptyset(&act.sa_mask); //清空sa_mask结构体成员 sigaddset(&act.sa_mask, SIGTSTP); /*在处理SIGQUIT信号程序中阻塞SIGTSTP信号*/ act.sa_handler=sa_user_handler; act.sa_flags=SA_RESTART; //被信号中断的系统调用会自行重启 sigaction(SIGQUIT, &act, NULL); //注册SIGQUIT信号处理函数 /*注册SIGTSTP信号处理函数部分*/ sigemptyset(&act.sa_mask); //清空sa_mask结构体成员 sigaddset(&act.sa_mask, SIGQUIT); /*在处理SIGTSTP信号程序中阻塞SIGQUIT信号*/ act.sa_handler=sa_user_handler; act.sa_flags=SA_RESTART; //被信号中断的系统调用会自行重启 sigaction(SIGTSTP, &act, NULL); //注册SIGTSTP信号处理函数 sigprocmask(SIG_UNBLOCK, ®ister_mask, NULL); /*注册信号处理完成后解除阻塞SIGQUIT、SIGTSTP信号*/ while(1); return 0; } /*2.子进程不产生僵尸进程的方法*/ #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <sys/types.h> #include <unistd.h> #include <string.h> #define handle_error(msg) \ do { perror(msg); exit(EXIT_FAILURE); } while (0) /** * 函数名:sa_quit_handler * 描述: 用户自定义SIGQUIT、SIGTSTP信号处理函数 * 参数: int signo -- 响应的信号 * 返回值:nonu */ void sa_user_handler(int signo){ /** *linux中,使用SA_NOPOSIX标志下,POSIX.1不指定在子进程终止时是否生成SIGCHLD信号, * 在这个例子中是会生成一个SIGCHLD信号;在其他一些实现中,则不是这样。 */ if(SIGCHLD == signo){ fprintf(stderr, "rec: SIGCHLD\n"); } } /*ctrl + z : 从键盘发送SIGTSTP信号给进程,暂停进程*/ /*ctrl + \ : 从键盘发送SIGQUIT信号给进程,进程退出*/ /*ctrl + c : 终止进程*/ int main(void){ struct sigaction act; sigset_t register_mask; pid_t ret; if((ret=fork())==-1){ handle_error("fork"); } if(0==ret){ /*在子进程中*/ write(STDERR_FILENO, (char *)"In child!\n", strlen("In child!\n")); sleep(3); write(STDOUT_FILENO, (char *)"child exit!\n", strlen("child exit\n!")); }else{ /*在父进程中*/ write(STDOUT_FILENO, (char *)"In parent!\n", strlen("In parent\n!")); sigemptyset(®ister_mask); //清空sigset_t结构体 sigaddset(®ister_mask, SIGQUIT|SIGTSTP); /*添加要阻塞的信号*/ sigprocmask(SIG_BLOCK, &act.sa_mask, NULL); /*注册信号处理函数前阻塞SIGCHLD、SIGQUIT、SIGTSTP信号*/ /*注册SIGQUIT信号处理函数部分*/ sigemptyset(&act.sa_mask); //清空sa_mask结构体成员 sigaddset(&act.sa_mask, SIGQUIT|SIGINT); /*在处理SIGCHLD信号程序中阻塞SIGQUIT、SIGINT信号*/ act.sa_handler=sa_user_handler; act.sa_flags=SA_NOCLDWAIT|SA_RESTART; /*被信号中断的系统调用会自行重启,子进程结束后不通知父进程,由init释放子进程资源*/ sigaction(SIGCHLD, &act, NULL); //注册SIGCHLD信号处理函数 sigprocmask(SIG_UNBLOCK, ®ister_mask, NULL); /*注册信号处理完成后解除阻塞SIGCHLD、SIGQUIT、SIGTSTP信号*/ while(1); } return 0; }
Linux --sigaction举例(改变信号默认操作)
最新推荐文章于 2025-03-26 13:22:21 发布