C语言 SIGCHLD 在 Linux 上的 SIGCONT 上发送,但不在 macOS 上发送



在主进程中,我听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 receivedn");
    fflush(stdout);
}
void    my_kill(pid_t pid, int signum)
{
    printf("Sending %dn", signum);
    fflush(stdout);
    kill(pid, signum);
    printf("Sent %dnn", 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

该行为是可选的。 实现不需要在继续时生成 SIGCHLD。 POSIX.1-2008(2016年版(中使用的语言是"可以"而不是"应":

当停止的进程继续时,可能会为其父进程生成 SIGCHLD 信号,除非父进程设置了SA_NOCLDSTOP标志。

- 系统接口,2.4.3 信号动作

。每当调用进程的任何停止子进程继续时,都会为调用进程生成 SIGCHLD 信号。

- 系统接口sigaction"说明">

重点补充。

我错过了什么吗?

应该不会。

这是预期的行为吗?

大概是的。

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

最新更新