Chinaunix首页 | 论坛 | 博客
  • 博客访问: 276170
  • 博文数量: 67
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 620
  • 用 户 组: 普通用户
  • 注册时间: 2015-07-12 19:56
文章分类

全部博文(67)

文章存档

2019年(1)

2018年(1)

2017年(4)

2016年(34)

2015年(27)

我的朋友

分类: LINUX

2015-08-21 13:08:57

一. 所有信号如下: 
[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次信号处理或者一次信号处理,不会看到第三次信号处理。当然,前提是发送所有信号的时间要比一次信号处理的时间短。










阅读(1171) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~