首页 文章

在UNIX中处理信号的区别

提问于
浏览
15

使用 sigprocmask() 屏蔽信号和使用 signal(<signal>, SIG_IGN) 忽略信号之间是否存在差异?

2 回答

  • 2

    阻止与忽略不同 . 通过使用 sigaction() 安装 SIG_IGN 来忽略信号 .

    在内核或进程生成信号之后,内核使其等待某些进程 . 一旦该过程作用于信号,就称该信号被传送到过程 . 进程可以阻止信号,该信号在信号被解除阻塞之前保持未决状态 . 未被阻止的信号将立即发送 . 信号掩码指定阻止哪些信号 . 进程可以确定哪些信号待处理 .

    大多数UNIX不会对同一待处理信号的多个实例进行排队;每个信号只有一个实例可以挂起 .

    对于待处理信号,将信号操作设置为 SIG_IGN 将导致待处理信号被丢弃,无论是否被阻止 .

    并且过程信号掩码包含当前被阻止的一组信号 .

    当一个过程阻塞一个信号时,信号的出现一直保持到信号被解锁(阻塞的信号不会丢失,而被忽略的信号确实丢失) .

  • 16

    当你屏蔽一个信号时,它实际上告诉内核这个信号赢了't be delivered to the process till the mask is it.This doesn' t意味着信号 wont occur ever again in the context of the process . 它只是放在一个队列中 . 这通常是在你想要接收信号但不在某些操作期间完成时 . 屏蔽信号通常意味着 this signal can mean something to me but let it wait if it comes before I finish with this job . 忽略的信号通常意味着信号对过程没用 .

    #include<stdio.h>
    #include<signal.h>
    #include<sys/types.h>
    int main()
    {
        sigset_t test; //test signal set
    
        alarm(1); //set alarm,SIGALRM generated after 1 second
        sigemptyset(&test);
    
        sigaddset(&test,SIGALRM);
        sigprocmask(SIG_SETMASK,&test,NULL); //mask sigalrm
        sleep(3); //sleep for 3 seconds ensuring the signal is generated and is         waiting in the queue
        sigprocmask(SIG_UNBLOCK,&test,NULL); //unblock
    }
    

    这是指情况1.信号被屏蔽 . 但 It lies there waiting and delivered as soon as you need it strace输出证实了这一点

    alarm(1)                                = 0
       rt_sigprocmask(SIG_SETMASK, [ALRM], NULL, 8) = 0
       rt_sigprocmask(SIG_BLOCK, [CHLD], [ALRM], 8) = 0
       rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
       rt_sigprocmask(SIG_SETMASK, [ALRM], NULL, 8) = 0
       nanosleep({3, 0}, 0xbfee9ea4)           = 0
       rt_sigprocmask(SIG_UNBLOCK, [ALRM], NULL, 8) = 0
       --- SIGALRM (Alarm clock) @ 0 (0) ---
       +++ killed by SIGALRM +++
    

    而对于第二种情况

    #include<stdio.h>
     #include<signal.h>
     int main()
    {
        alarm(1);
        signal(SIGALRM,SIG_IGN);
    
        sleep(3);
        signal(SIGALRM,SIG_DFL);
        return 0;
    }
    

    strace o / p暗示了一个不同的故事

    alarm(1)                                = 0
       rt_sigaction(SIGALRM, {SIG_IGN, [ALRM], SA_RESTART}, {SIG_DFL, [], 0}, 8) = 0
       rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
       rt_sigaction(SIGCHLD, NULL, {SIG_DFL, [], 0}, 8) = 0
       rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
       nanosleep({3, 0}, {2, 691998})          = ? ERESTART_RESTARTBLOCK (To be restarted)
       --- SIGALRM (Alarm clock) @ 0 (0) ---
       restart_syscall(<... resuming interrupted call ...>) = 0
       rt_sigaction(SIGALRM, {SIG_DFL, [ALRM], SA_RESTART}, {SIG_IGN, [ALRM], SA_RESTART},                         8) = 0
       exit_group(0)                           = ?
    

    信号确实得到 delivered 但除了打断(并重新启动睡眠)之外没有任何事情发生 .

相关问题