一. 所有信号如下:
[aguo@/work/aguo/newport2/components/foundation]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
[aguo@/work/aguo/newport2/components/foundation]
二. 实时信号(可靠信号)范围是
SIGRTMIN - SIGRTMAX 之间;非实时信号(不可靠信号)是小于SIGRTMIN 的所有信号。
三. 测试不可靠信号代码如下:
[aguo@~/test]cat non-real-time-sign.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <string.h>
//#define MYSIGNAL SIGRTMIN+5
//
#define MYSIGNAL SIGTERM
void sig_handler(int signum)
{
psignal(signum, "catch a signal");
sleep(3);
}
int main(int argc, char **argv)
{
sigset_t block, pending;
int sig, flag;
#if 0
signal(MYSIGNAL, sig_handler);
#else
struct sigaction act;
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(MYSIGNAL, &act, NULL);
#endif
sigemptyset(&block);
sigaddset(&block, MYSIGNAL);
printf("block signal NSIG=%d, SIGRTMIN=%d, SIGRTMAX=%d\n", NSIG, SIGRTMIN, SIGRTMAX);
sigprocmask(SIG_BLOCK, &block, NULL);
printf("---> send a signal --->\n");
kill(getpid(), MYSIGNAL);
printf("---> send a signal --->\n");
kill(getpid(), MYSIGNAL);
printf("---> send a signal --->\n");
kill(getpid(), MYSIGNAL);
printf("---> send a signal --->\n");
kill(getpid(), MYSIGNAL);
flag = 0;
sigpending(&pending);
for (sig = 1; sig < NSIG; sig++) {
if (sigismember(&pending, sig)) {
flag = 1;
psignal(sig, "this signal is pending");
}
}
if (flag == 0) {
printf("no pending signal\n");
}
printf("unblock signal\n");
sigprocmask(SIG_UNBLOCK, &block, NULL);
flag = 0;
sigpending(&pending);
for (sig = 1; sig < NSIG; sig++) {
if (sigismember(&pending, sig)) {
flag = 1;
psignal(sig, "a pending signal");
}
}
if (flag == 0) {
printf("no pending signal\n");
}
return 0;
}
测试过程如下:
[aguo@~/test]make non-real-time-sign
cc non-real-time-sign.c -o non-real-time-sign
[aguo@~/test]./non-real-time-sign
block signal NSIG=65, SIGRTMIN=34, SIGRTMAX=64
---> send a signal --->
---> send a signal --->
---> send a signal --->
---> send a signal --->
this signal is pending: Terminated
unblock signal
catch a signal: Terminated
no pending signal
[aguo@~/test]
当block信号SIGINT时,发送四次请求信号,最后只会得到一个信号;也就是信号SIGINT 阻塞但是没有排队。
四,测试实时信号如下。
[aguo@~/test]cat real-time-sign.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <string.h>
#define MYSIGNAL SIGRTMIN+5
//
//#define MYSIGNAL SIGTERM
void sig_handler(int signum)
{
psignal(signum, "catch a signal");
sleep(2);
}
int main(int argc, char **argv)
{
sigset_t block, pending;
int sig, flag;
struct sigaction act;
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(MYSIGNAL, &act, NULL);
sigemptyset(&block);
sigaddset(&block, MYSIGNAL);
printf("block signal\n");
sigprocmask(SIG_BLOCK, &block, NULL);
printf("---> send a signal --->\n");
kill(getpid(), MYSIGNAL);
printf("---> send a signal --->\n");
kill(getpid(), MYSIGNAL);
printf("---> send a signal --->\n");
kill(getpid(), MYSIGNAL);
printf("---> send a signal --->\n");
kill(getpid(), MYSIGNAL);
flag = 0;
sigpending(&pending);
for (sig = 1; sig < NSIG; sig++) {
if (sigismember(&pending, sig)) {
flag = 1;
psignal(sig, "this signal is pending");
}
}
if (flag == 0) {
printf("no pending signal\n");
}
//sleep(15);
printf("unblock signal\n");
sigprocmask(SIG_UNBLOCK, &block, NULL);
flag = 0;
sigpending(&pending);
for (sig = 1; sig < NSIG; sig++) {
if (sigismember(&pending, sig)) {
flag = 1;
psignal(sig, "a pending signal");
}
}
if (flag == 0) {
printf("no pending signal\n");
}
return 0;
}
[aguo@~/test]make ^C
[aguo@~/test]rm real-time-sign
[aguo@~/test]make real-time-sign
cc real-time-sign.c -o real-time-sign
[aguo@~/test]./real-time-sign
block signal
---> send a signal --->
---> send a signal --->
---> send a signal --->
---> send a signal --->
this signal is pending: Unknown signal 39
unblock signal
catch a signal: Unknown signal 39
catch a signal: Unknown signal 39
catch a signal: Unknown signal 39
catch a signal: Unknown signal 39
no pending signal
[aguo@~/test]
当block 信号39时,发送4次请求信号39,当unblock 信号39时,有4次信号处理。也就说实时信号是阻塞并且排队的。
五,换一种测试方法,代码如下
[aguo@~/test]cat signal-s.c
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <error.h>
#include <string.h>
//#define MYSIGNAL SIGRTMIN+5
//
#define MYSIGNAL SIGINT
void sig_handler(int signum)
{
psignal(signum, "catch a signal");
sleep(15);
}
int main(int argc, char **argv)
{
sigset_t block, pending;
int sig, flag;
struct sigaction act;
act.sa_handler = sig_handler;
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
sigaction(MYSIGNAL, &act, NULL);
while(1){
sleep(1);
printf("#####\n");
}
return 0;
}
[aguo@~/test]
[aguo@~/test]make signal-s
cc signal-s.c -o signal-s
[aguo@~/test]./signal-s
#####
在另一个终端 这样测试
[aguo@~]cat /proc/27261/status
Name: signal-s
State: S (sleeping)
Tgid: 27261
Pid: 27261
PPid: 16631
TracerPid: 0
Uid: 564 564 564 564
Gid: 565 565 565 565
Utrace: 0
FDSize: 256
Groups: 565
VmPeak: 4032 kB
VmSize: 3924 kB
VmLck: 0 kB
VmHWM: 376 kB
VmRSS: 376 kB
VmData: 48 kB
VmStk: 88 kB
VmExe: 4 kB
VmLib: 1704 kB
VmPTE: 32 kB
VmSwap: 0 kB
Threads: 1
SigQ: 0/192021
SigPnd: 0000000000000000
ShdPnd: 0000000000000000
SigBlk: 0000000000000000
SigIgn: 0000000000000000
SigCgt: 0000000000000002
CapInh: 0000000000000000
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: ffffffffffffffff
Cpus_allowed: ffffff
Cpus_allowed_list: 0-23
Mems_allowed: 00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000000,00000003
Mems_allowed_list: 0-1
voluntary_ctxt_switches: 27
nonvoluntary_ctxt_switches: 1
[aguo@~]
[aguo@~]kill -s 27261;
-bash: kill: 27261: invalid signal specification
[aguo@~]kill -s 2 27261 ;kill -s 2 27261 ;kill -s 2 27261 ;kill -s 2 27261 ;kill -s 2 27261 ;kill -s 2 27261 ;kill -s 2 27261 ;kill -s 2 27261 ;kill -s 2 27261 ;
[aguo@~]
[aguo@~]
你可以看到信号2是捕捉的;但是无论你发送kill 信号多块,最多只会有2个信号被捕捉到。有时候是一个当kill命令比较少时。
分析如下:
信号处理流程: 捕捉信号--》block 信号--》信号处理函数调用--》unblock 信号。所以你看到的就是你发送很少的同一个信号时,可能在捕捉信号和block信号之间完成,所以你只能看到一个信号处理。当发送很多信号时,可能一部分信号会在block信号和信号处理函数调用之间递送,这样就会被阻塞,由于不支持排队,当信号处理函数调用完毕后,block的信号会被再次递送,所以你会看到2次信号处理或者一次信号处理,不会看到第三次信号处理。当然,前提是发送所有信号的时间要比一次信号处理的时间短。
阅读(1274) | 评论(0) | 转发(0) |