首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SIGCHLD没有被抓

SIGCHLD没有被抓
EN

Stack Overflow用户
提问于 2013-08-14 09:38:20
回答 3查看 3.3K关注 0票数 0

我打算在父进程休眠10 s时,将以下代码作为子进程来分叉和执行“睡眠3”。我期望父进程在3s后接收SIGCHLD,这时“睡眠3”就会出现。

这是不会发生的,相反,我得到:

代码语言:javascript
复制
main
parent process
parent sleeping for 10s
child process
child start, command: /bin/sleep, args: 0x7fffc68c8000, env: 0x7fffc68c8020

ps -ef显示

代码语言:javascript
复制
chris    10578 10577  0 10:35 pts/25   00:00:00 /bin/sleep 3

其次是:

代码语言:javascript
复制
chris    10578 10577  0 10:35 pts/25   00:00:00 [sleep] <defunct>

接下来的七秒钟(此时父进程退出)。

问题是从来没有调用过clean_up_child_process

我犯了什么错误?

僵尸测试.c:

代码语言:javascript
复制
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <strings.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>

pid_t child_pid;

sig_atomic_t child_exit_status;

void clean_up_child_process (int signal_number) {
    printf("signal received\n");
    /* Clean up the child process. */
    int status;
    wait (&status);
    /* Store its exit status in a global variable. */
    child_exit_status = status;
    printf("child_exit_status %i\n", status);
}

int main(int argc, char **argv) {
    printf("main\n");

    int pid = fork();

    if (pid == 0) {
        printf("child process\n");
        signal(SIGCHLD, clean_up_child_process);

        char *args[] = { "/bin/sleep", "3", NULL };
        char *env[] = { NULL };
        printf("child start, command: %s, args: %p, env: %p\n", args[0], args, env);
        int ret = execve(args[0], args, env);

        // if we get here, then the execve has failed
        printf("exec of the child process failed %i\n", ret);
    } else if (pid > 0) {
        printf("parent process\n");
        child_pid = pid;
    } else {
        perror("fork failed\n");
    }
    printf("parent sleeping for 10s\n");
    sleep(10);
    return 0;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-08-14 09:43:55

您告诉子进程等待子进程完成,然后子进程调用execve,它不会创建子进程,而是将当前程序替换为正在执行的程序。

您可能希望父节点拦截子节点(即在执行signal调用之前进行fork调用)。

票数 2
EN

Stack Overflow用户

发布于 2013-08-14 09:42:32

找到它:对信号的调用不应该在pid == 0分支中,因为当execve被调用时,该进程将被完全替换。

将信号调用移到if上面解决了这个问题。

票数 1
EN

Stack Overflow用户

发布于 2013-08-14 09:54:58

这一行:signal(SIGCHLD, clean_up_child_process);应该用(pid>0)而不是(pid == 0)

参见谢赫德

SIGCHLD信号是在子进程退出、中断或被中断后恢复时发送给其子进程的父的。默认情况下,信号被忽略。

因此,父进程接收到SIGCHLD,父进程调用clean_up_child_process。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18228163

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档