2011-04-20 58 views

回答

14

封锁不同于忽视。您通过安装SIG_IGNsigaction()忽略信号。

内核或进程生成一个信号后,内核使其等待某个进程。一旦过程作用在信号上,信号就被说成传递给一个过程。一个进程可能会阻塞一个信号,这个信号会一直处于待处理状态,直到它被解除阻塞。未被阻止的信号将立即传送。信号掩码指定哪些信号被阻塞。一个进程可以确定哪些信号正在等待。

大多数UNIX不会对相同的未决信号的多个实例进行排队;每个信号只有一个实例可以挂起。

将信号动作设置为SIG_IGN对于未决信号将导致挂起的信号被丢弃,不管它是否被阻塞。

而过程信号掩码包含当前被阻塞的一组信号。

当一个进程阻塞信号时,信号的出现被保持,直到信号被解除阻塞(被阻塞的信号不会丢失,而被忽略的信号会丢失)。

2

当你屏蔽一个信号时,它实际上告诉内核这个信号将不会被传送到该过程,直到屏蔽它为止。这并不意味着信号不会在过程的上下文中再次发生 。它只是放在一个队列中。这通常是在你想接收信号时完成的,但是在某些操作过程中没有。掩码信号通常意味着这个信号对我来说可能意味着什么,但是如果它在我完成之前就让它等待工作。 忽略的信号通常意味着该信号对该过程没有用处。

#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.信号masked.But 它躺在那里等待,只要你需要它 的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)       = ? 

信号确实有交付但除了中断(并重新启动睡眠)之外,没有任何事情发生。