sigaction函数中关于sa_mask的解释

使用 man sigaction 查看手册,对sa_mask的描述是这样的:

sa_mask  specifies  a  mask  of  signals which should be blocked (i.e., added to the signal mask of the thread in which the signal handler is invoked) during execution of the signal handler.  In addition, the signal which triggered the handler will be blocked, unless the SA_NODEFER flag is used.

 我的理解是:如果将某个信号加入sa_mask信号集,那么在触发该信号并且执行回调函数之后期间,如果再有这个信号触发,将被阻塞。即不能同时执行两个相同的信号处理函数。

 参考sigaction()之sa_mask这篇文章的说法:

sigset_t sa_mask 是一个信号集,在调用该信号捕捉函数之前,将需要block的信号加入这个sa_mask,仅当信号捕捉函数正在执行时,才阻塞sa_mask中的信号,当从信号捕捉函数返回时进程的信号屏蔽字复位为原先值。

 

Q1:这个复位动作是sigaction函数内部处理,还是由调用者自己处理呢?

  由sigaction函数自动复位,不用我自己再去处理。

Q2:设置sa_mask的目的?

  在调用信号处理程序时就能阻塞某些信号。注意仅仅是在信号处理程序正在执行时才能阻塞某些信号,如果信号处理程序执行完了,那么依然能接收到这些信号。
在信号处理程序被调用时,操作系统建立的新信号屏蔽字包括正被递送的信号,也就是说自己也被阻塞,除非设置了SA_NODEFER。
        因此保证了在处理一个给定的信号时,如果这种信号再次发生,通常并不将它们排队,所以如果在某种信号被阻塞时它发生了5次,那么对这种信号解除阻塞后,其信号处理函数通常只会被调用一次。

Q3:对于不同信号,当信号A被捕捉到并且信号A的handler正被调用时,信号B产生了,
  如果信号B没有被设置阻塞,那么正常接收信号B并调用自己的信号处理程序。另外,如果信号A的信号处理程序中有sleep函数,那么当进程接收到信号B并处理完后,sleep函数立即返回(如果睡眠时间足够长的话)
  如果信号B有被设置成阻塞,那么信号B被阻塞,直到信号A的信号处理程序结束,信号B才被接收并执行信号B的信号处理程序。

        如果在信号A的信号处理程序正在执行时,信号B连续发生了多次,那么当信号B的阻塞解除后,信号B的信号处理程序只执行一次。

        如果信号A的信号处理程序没有执行或已经执行完,信号B不会被阻塞,正常接收并执行信号B的信号处理程序。
Q4:对于相同信号,当一个信号A被捕捉到并且信号A的handler正被调用时

        又产生了一个信号A,第二次产生的信号被阻塞,直到第一次产生的信号A处理完后才被递送;

        如果连续产生了多次信号,当信号解除阻塞后,信号处理函数只执行一次。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`sa_sigaction` 是一个结构体类型,在 C 语言用于指定信号处理函数的方式。它通常用于设置信号处理函数,以便在程序收到特定信号时执行相应的操作。 它的完整定义如下: ```c struct sigaction { void (*sa_handler)(int); void (*sa_sigaction)(int, siginfo_t *, void *); sigset_t sa_mask; int sa_flags; void (*sa_restorer)(void); }; ``` 其,`sa_handler` 和 `sa_sigaction` 两个字段是用于指定信号处理函数的指针。`sa_handler` 字段指定了一个简单的信号处理函数,而 `sa_sigaction` 字段指定了一个更复杂的信号处理函数,可以接收额外的信息。 `sa_mask` 字段表示在处理信号时需要阻塞的其他信号集合。当处理某个信号时,通常需要阻塞其他信号,以避免信号处理函数被其他信号断。 `sa_flags` 字段表示信号处理的行为标志,可以控制信号处理函数的行为。 `sa_restorer` 字段是一个已过时的字段,通常不再使用。 使用 `sigaction` 函数可以将 `struct sigaction` 结构体的信号处理函数注册到特定的信号上,示例代码如下: ```c #include <stdio.h> #include <signal.h> void handle_signal(int signum) { printf("Received signal: %d\n", signum); } int main() { struct sigaction sa; sa.sa_handler = handle_signal; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGINT, &sa, NULL); // 注册 SIGINT 信号处理函数 // 一些其他的程序逻辑... return 0; } ``` 在上述示例,`handle_signal` 函数被注册为 `SIGINT` 信号的处理函数,当程序收到 `SIGINT` 信号时,会执行 `handle_signal` 函数

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值