在服務器端後臺開發中,經常須要寫 daemon 程序在後臺默默執行一些任務。除了正常的邏輯以外,還須要考慮處理異常退出時怎麼辦。這時能夠用到 signal 這個函數來註冊異常信號的回調函數。html
#include <iostream> #include <csignal> #include <time.h> #include <stdlib.h> #include <unistd.h> using namespace std; void signalHandler( int signum ) { cout << "Interrupt signal (" << signum << ") received.\n"; // cleanup and close up stuff here // terminate program exit(signum); } int main () { // register signal SIGINT and signal handler signal(SIGINT, signalHandler); while(1){ cout << "Going to sleep...." << endl; sleep(1); } return 0; }
當 CTRL+C 時發出 SIGINT 信號,程序打印linux
Going to sleep.. Going to sleep.. Going to sleep.. Interrupt signal (2) received.
用 GDB bt 命令能夠查看堆棧信息,在程序中也可使用 backtrace 函數來記錄當前進程的堆棧信息。一旦接收到系統異常信號,將堆棧信息 dump 到文件中,便於分析定位問題ios
void BackTraceDumper(int signo) { static const uint32_t MAX_STACK_BACKTRACE_SIZE = 100; static void* stack_array[MAX_STACK_BACKTRACE_SIZE]; uint32_t size = backtrace(stack_array, MAX_STACK_BACKTRACE_SIZE); char path[256]; sprintf(path, "/home/user/tmp/core_%lu", time(NULL)); int core_file_fd = open(path, O_CREAT | O_WRONLY, 0444); backtrace_symbols_fd(stack_array, size, core_file_fd); close(core_file_fd); std::exit(-1); }
static void SignalHandler(void) { signal(SIGPIPE, SIG_IGN); signal(SIGALRM, SIG_IGN); signal(SIGCHLD, SIG_IGN); sigset(SIGHUP, SIG_IGN); sigset(SIGINT, SignalStop); sigset(SIGTERM, SignalStop); sigset(SIGUSR1, SignalStop); sigset(SIGABRT, BackTraceDumper); sigset(SIGFPE, BackTraceDumper); sigset(SIGBUS, BackTraceDumper); sigset(SIGSEGV, BackTraceDumper); return; }
使用服務器
kill -SIGINT 20482
發送 SIGINT 信號測試函數
kill -l
顯示測試
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX
http://www.embeddedlinux.org.cn/html/jishuzixun/201211/19-2388.htmlui