在主要流程中,我听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
答案 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也缺乏这种支持。