繁体   English   中英

sigwait() 在 macOS 和 Linux 中的行为是否不同?

[英]Does sigwait() behave differently in macOS and Linux?

我发现以下代码在 macOS 和 Linux 中的工作方式不同:

#include <signal.h>
#include <unistd.h>
#include <stdio.h>

void catcher( int sig ) {
    printf( "Signal catcher called for signal %d\n", sig );
}

int main( int argc, char *argv[] ) 
{
    struct sigaction sigact;
    sigset_t waitset;
    int sig;
    int result = 0;

    sigemptyset( &sigact.sa_mask );
    sigact.sa_flags = 0;
    sigact.sa_handler = catcher;

    sigaction( SIGINT, &sigact, NULL );

    sigemptyset( &waitset );
    sigaddset( &waitset, SIGHUP);

    result = sigwait(&waitset, &sig) ;
    if(result == 0)
    {
        printf( "sigwait() returned for signal %d\n", sig );
    }
}

当在 macOS 上运行并将 SIGINT 发送到进程时,仅在发送 SIGHUP 后才执行其处理程序(从而导致 sigwait() 返回)。 换句话说,它看起来 sigwait() 在等待期间阻塞了其等待掩码之外的所有信号。 当相同的程序在 Linux 上运行时,SIGINT 被传递,即处理器运行,只要一个 SIGINT 被发送到进程。 因此,它在 Linux 中看起来 sigwait() 不会阻止其等待掩码之外的信号。 哪个是标准行为? SUSv3 没有明确说明。

sigwait 显然没有指定阻止任何信号 如果它在 MacOS X 上这样做,这似乎是一个错误。

OS X 不会阻止无关信号,而是暂停进程 à la SIGSTOP。

我发现这是规范(IEEE Std 1003.1-2017) 的合理实现,它要求sigwait(set, &s)挂起调用线程,直到set中的至少一个信号变为挂起。

就像真正的 STOP 一样,OS X 会阻止无法阻止的 SIGKILL 直到进程恢复。 ps可以看到 STOP 和sigwait之间的差异,当然每个进程恢复的过程都不同(CONT 与set ),但它们本质上是相同的进程状态。

另一方面,在我看来,Linux 认为sigwait是可中断的,而且用户定义的操作是通过 SA_RESTART 安装的。 调用用户定义的处理程序,并立即遵守 KILL。 在我看来,这种行为更有用,但不符合规范——如果线程可以执行用户定义的信号处理程序,它就不会挂起。

当然,这种情况有点做作,因为sigwait确实是为多线程程序设计的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM