信号学习:
1。简单点用signal(主要就1个api,signal(SIGINT, SignalHandler)和signal(SIGINT, SIG_IGN)就是全部了);
2。复杂点用sigaction(可以设置在handling期间,允许/不允许哪些信号打断自己);
3。当前线程handling过程中,当前线程不会因为相同signal再次进入handler,但当前线程可以被别的signal打断重新进入handler,别的线程可以进入handler;
例如下面这个例子,只有一个主线程,先被SIGINT打断进入handler,虽然又被SIGTERM打断再次进入handler:
#0 0x00007f7cc55dc200 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82
#1 0x00007f7cc55dc090 in __sleep (seconds=<value optimized out>) at ../sysdeps/unix/sysv/linux/sleep.c:138
#2 0x0000000000468300 in SignalHandler (sig=15) at src/dispatcher2_server.cpp:78
#3 <signal handler called>
#4 0x00007f7cc55dc200 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82
#5 0x00007f7cc55dc090 in __sleep (seconds=<value optimized out>) at ../sysdeps/unix/sysv/linux/sleep.c:138
#6 0x0000000000468300 in SignalHandler (sig=2) at src/dispatcher2_server.cpp:78
#7 <signal handler called>
#8 0x00007f7cc55dc200 in __nanosleep_nocancel () at ../sysdeps/unix/syscall-template.S:82
#9 0x00007f7cc55dc090 in __sleep (seconds=<value optimized out>) at ../sysdeps/unix/sysv/linux/sleep.c:138
#10 0x000000000046844a in main (argc=1, argv=0x7fff048454a8) at src/dispatcher2_server.cpp:102
demo:
static void SignalHandler(int sig) {
if (SIGTERM == sig || SIGINT == sig) {
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_IGN;
sigaction(SIGINT, &sa, NULL); // keep other threads from entering this handler
sigaction(SIGTERM, &sa, NULL); // keep other threads from entering this handler
//...
}
}
struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_handler = SignalHandler;
sigfillset(&sa.sa_mask); // block every signal during handling
sigaction(SIGINT, &sa, NULL);
sigaction(SIGTERM, &sa, NULL);
介绍:http://www.alexonlinux.com/signal-handling-in-linux
demo:http://aspyct.org/blog/2012/08/25/unix-signal-handling-example/