UNIX 中信号处理的差异

发布于 2024-11-02 05:34:10 字数 78 浏览 0 评论 0原文

使用 sigprocmask() 屏蔽信号和使用 signal(, SIG_IGN) 忽略信号之间有区别吗?

Is there a difference between masking a signal using sigprocmask() and ignoring a signal using signal(<signal>, SIG_IGN)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

执笏见 2024-11-09 05:34:10

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

内核或进程生成信号后,内核会将其挂起给某些进程。一旦进程对信号进行操作,信号就被传递给进程。进程可能会阻塞信号,从而使信号处于挂起状态,直到其被解除阻塞为止。未被阻塞的信号将立即被传递。信号掩码指定哪些信号被阻止。进程可以确定哪些信号待处理。

大多数 UNIX 不会对同一挂起信号的多个实例进行排队;每个信号只能有一个实例处于待处理状态。

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

进程信号掩码包含当前被阻止的信号集。

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

Blocking is different from ignoring. You ignore a signal by installing SIG_IGN with sigaction().

After a signal is generated by the kernel or a process, the kernel makes it pending to some process(es). The signal is said to be delivered to a process once the process acts on the signal. A process may block a signal, which leaves the signal pending until it is unblocked. A signal which is not blocked will be delivered immediately. The signal mask specifies which signals are blocked. A process can determine which signals are pending.

Most UNIX's will not queue multiple instances of the same pending signal; only one instance of each signal can be pending.

Setting a signal action to SIG_IGN for a signal that is pending will cause the pending signal to be discarded, whether or not it is blocked.

And the process signal mask contains the set of signals that are currently blocked.

When a process blocks a signal, an occurrence of the signal is held until the signal is unblocked (blocked signals do not get lost, whereas ignored signals do get lost).

樱娆 2024-11-09 05:34:10

当您屏蔽一个信号时,它实际上告诉内核该信号不会被传递到进程,直到屏蔽为止。这并不意味着该信号不会在进程的上下文中再次出现.它只是放入队列中。这通常是在您想要接收信号但不是在某些操作期间完成的。屏蔽信号通常意味着此信号对我来说可能意味着一些东西,但如果它在我之前出现,请让它等待完成这项工作
被忽略的信号通常意味着该信号对进程没有用处。

#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。信号被屏蔽。但是它躺在那里等待并在您需要时立即发送
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)                           = ?

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

When you mask a signal it actually tells the kernel that this signal won't be delivered to the process till the mask is it.This doesn't means the signal wont occur ever again in the context of the process.Its just placed in a queue.This is usually done when you want to receive the signal but not during certain operation.A masked signal usually implies this signal can mean something to me but let it wait if it comes before I finish with this job.
An ignored signal usually means that the signal is of no use to the process.

#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
}

This refers to case 1.The signal is masked.But It lies there waiting and delivered as soon as you need it
The strace output confirms this

   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 +++

While for the second case

 #include<stdio.h>
 #include<signal.h>
 int main()
{
    alarm(1);
    signal(SIGALRM,SIG_IGN);

    sleep(3);
    signal(SIGALRM,SIG_DFL);
    return 0;
}

The strace o/p suggest a different story

   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)                           = ?

The signal did got delivered but nothing happened except interrupting(and restarting sleep).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文