SIGCHLD是在Linux上的SIGCONT上发送的,而不是在macOS上发送的

时间:2018-01-28 15:25:30

标签: c linux macos signals child-process

在主要流程中,我听SIGCHLD:

signal(SIGCHLD, &my_handler);

然后我fork()execv()让它在后台运行(例如/ bin / cat)。

当我尝试从终端向子进程发送SIGSTOP时,my_handler()被调用。但是当我尝试向它发送SIGCONT时,处理程序不会在macOS上调用,但它在我的Ubuntu上执行。

曼:

  

SIGCHLD:子状态已更改。

我错过了什么吗?这是预期的行为吗?我在Ubuntu上编写了我的应用程序,并期望它也可以在Mac上运行。

我也尝试使用sigaction(),但效果相同。

以下是示例代码:

#include <signal.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>

void    my_handler(int signum)
{
    printf("\t SIGCHLD received\n");
    fflush(stdout);
}

void    my_kill(pid_t pid, int signum)
{
    printf("Sending %d\n", signum);
    fflush(stdout);

    kill(pid, signum);

    printf("Sent %d\n\n", signum);
    fflush(stdout);
}

int main()
{
    pid_t   pid;
    char    *cat_args[2] = {"/bin/cat", NULL};

    signal(SIGCHLD, &my_handler);
    pid = fork();

    if (pid == 0)
    {
        execv("/bin/cat", cat_args);
    }
    else
    {   
        my_kill(pid, SIGSTOP);
        my_kill(pid, SIGCONT);
        wait(NULL);
    }
    return 0;
}

使用macOS上的输出:

Sending 17
         SIGCHLD received
Sent 17

Sending 19
Sent 19

2 个答案:

答案 0 :(得分:5)

该行为是可选的。实现不需要在继续时生成SIGCHLD。 POSIX.1-2008(2016版)中使用的语言是&#34;可能&#34;而不是&#34;&#34;:

  

当一个停止的进程继续时,除非父进程设置了SA_NOCLDSTOP标志,否则可以为其父进程生成一个SIGCHLD信号

- System Interfaces, 2.4.3 Signal Actions

  

...每当任何已停止的子进程继续运行时,都可以为调用进程生成SIGCHLD信号

-  System Interfaces sigaction "Description"

强调补充说。

答案 1 :(得分:2)

  

我错过了什么吗?

可能不是。

  

这是预期的行为吗?

可能是的。

OSX基于4.4 BSD,并且该BSD根本不支持在孩子继续时向父母发送SIGCHLD。早期版本的Linux也缺乏这种支持。